home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / PENTOPT.ZIP / PENTOPT.TXT < prev   
Text File  |  1997-02-28  |  143KB  |  3,096 lines

  1. HOW TO OPTIMIZE FOR THE PENTIUM PROCESSOR
  2. *****************************************
  3. Copyright (c) 1996, 1997 by Agner Fog. Last modified 1997-02-28.
  4.  
  5. Contents:
  6.  
  7. 1.  introduction
  8. 2.  literature
  9. 3.  debugging and verifying
  10. 4.  memory model
  11. 5.  alignment
  12. 6.  cache
  13. 7.  address generation interlock
  14. 8.  pairing integer instructions
  15. 9.  first time vs. repeated execution
  16. 10. imperfect pairing
  17. 11. splitting complex instructions into simpler ones
  18. 12. jumps and branches
  19. 13. prefixes
  20. 14. reducing code size
  21. 15. scheduling floating point code
  22. 16. loops
  23. 17. discussion of special instructions
  24. 18. using integer instructions to do floating point operations
  25. 19. using floating point instructions to do integer operations
  26. 20. list of integer instructions
  27. 21. list of floating point instructions
  28. 22. testing code speed
  29. 23. considerations for other microprocessors
  30.  
  31.  
  32. 1. INTRODUCTION
  33. ===============
  34. This manual describes in detail how to write optimized assembly language
  35. code, with particular focus on the Pentium(R) microprocessor.
  36.  
  37. This manual is more comprehensive and exact than other sources of
  38. information and contains many details not found anywhere else.
  39. This information will enable you in many cases to calculate exactly how
  40. many clock cycles a piece of code will take.
  41.  
  42. The information in this manual is based on my own research. This research
  43. has so far covered only the Pentium Processor without MMX. The Pentium
  44. with MMX behaves almost the same. Differences are mentioned where
  45. appropriate. This manual will be updated later with more information on
  46. the Pentium with MMX. The PentiumPro and PentiumII processors are very
  47. different, and will be covered only briefly. I have no plans of doing
  48. research on the PentiumPro and PentiumII processors.
  49.  
  50. Programming in assembly language is much more difficult than high level
  51. language. Making bugs is very easy, and finding them is very difficult. Now
  52. you have been warned! It is assumed that the reader is already experienced
  53. in assembly programming. If not, then please read some books on the subject
  54. and get some programming experience before you begin to do complicated
  55. optimations.
  56.  
  57. The hardware design of the Pentium chip has many features which are
  58. optimized specifically for some commonly used instructions or instruction
  59. combinations, rather than using general optimation methods. Consequently,
  60. the rules for optimizing software for this design are quite complicated
  61. and have many exceptions, but the possible gain in performance may be
  62. substantial.
  63.  
  64. Before you start to convert your code to assembly, make sure that your
  65. algorithm is optimal. Often you can improve a piece of code much more by
  66. improving the algorithm than by converting it to assembler code.
  67.  
  68. Some high level language compilers offer relatively good optimation for
  69. the Pentium, and further optimation by hand may not be worth the effort
  70. except for the most critical pieces of code - or for the sport of it.
  71.  
  72. Please don't send your programming questions to me. I am not gonna do your
  73. homework for you.
  74.  
  75. Good luck with your hunt for nanoseconds!
  76.  
  77. PS. I have deliberately misspelled 'optimization' because I think
  78. 'optimation' sounds better.
  79.  
  80.  
  81. 2. LITERATURE
  82. =============
  83. A lot of useful literature can be downloaded for free from Intel's www
  84. site or acquired in print or on CD-ROM.
  85.  
  86. I will not give the URL's here because they change very often.
  87. You can find the documents you need by using the search facilities at:
  88. http://www.intel.com/sites/developer/search.htm or follow the links from
  89. http://announce.com/agner/assem
  90.  
  91. Some documents are in .PDF format. If you don't have software for viewing
  92. or printing .PDF files, then you may download the Acrobat file reader from
  93. www.adobe.com
  94.  
  95. The most useful document is Intel's application note:
  96. 'AP-526 Optimizations for Intel's 32-bit Processors'
  97.  
  98. Beginners may use a funny tutorial named "Optimizing Applications for the
  99. Pentium Processor"
  100.  
  101. Optimations for the PentiumPro and PentiumII processors are described in
  102. 'AP-526 Optimizations for Intel's 32-bit Processors' and in the tutorial
  103. 'Optimizing for the Pentium« Pro Processor Family'.
  104.  
  105. The use of MMX instructions for optimizing specific applications are
  106. described in several application notes. The MMX instruction set is
  107. described in various manuals and tutorials.
  108.  
  109. A lot of other sources than Intel also have useful information. These
  110. sources are listed in the FAQ for the newsgroup comp.lang.asm.x86.
  111. The shareware editor ASMEDIT has an online help which covers all
  112. instruction codes etc. It is available from:
  113. http://www.inf.tu-dresden.de/~ok3/asmedit.html
  114.  
  115. For other internet ressources follow the links from
  116. http://announce.com/agner/assem/
  117.  
  118.  
  119.  
  120. 3. DEBUGGING AND VERIFYING
  121. ==========================
  122. Debugging assembly code can be quite hard and frustrating, as you probably
  123. already have discovered. I would recommend that you start with writing the
  124. piece of code you want to optimize as a subroutine in a high level language.
  125. Next, write a test program that will test your subroutine thoroughly. Make
  126. sure the test program goes into all branches and special cases.
  127.  
  128. When your high level language subroutine works with your test program, then
  129. you are ready to translate the code to assembly language (some high level
  130. compilers will do this for you), and test it on the test program.
  131.  
  132. Then you can start to optimize. Each time you have made a modification you
  133. should run it on the test program to see if it works correctly.
  134.  
  135. Number all your versions and save them so that you can go back and test
  136. them again in case you discover an error which the test program didn't
  137. catch (such as writing to a wrong address).
  138.  
  139. Test the speed of the most critical part of your program with the method
  140. described in chapter 22. If the code is significantly slower than expected,
  141. then the most probable reasons are: cache misses (chapter 6), misaligned
  142. operands (chapter 5), and first time penalty (chapter 9).
  143.  
  144.  
  145. 4. MEMORY MODEL
  146. ===============
  147. The Pentium is designed primarily for 32 bit code, and it's performance is 
  148. inferior on 16 bit code. Segmenting your code and data also degrades
  149. performance significantly, so you should generally prefer 32 bit flat mode, 
  150. and an operating system which supports this mode (e.g. Windows 95, OS/2, or
  151. a 32 bit DOS extender). The code examples shown in this manual assume a 32
  152. bit flat memory model, unless otherwise specified.
  153.  
  154.  
  155. 5. ALIGNMENT
  156. ============
  157. All data in RAM should be aligned to addresses divisible by 2, 4, or 8
  158. according to this scheme:
  159.  
  160. operand size      alignment
  161. ---------------------------
  162. 1  (byte)          1
  163. 2  (word)          2    (or address MOD 4 >< 3. other proc. require align by 2)
  164. 4  (dword)         4
  165. 6  (fword)         4    (Pentium Pro requires alignment by 8)
  166. 8  (qword)         8
  167. 10 (tbyte)         8    (Pentium Pro requires alignment by 16)
  168.  
  169. Misaligned data will take at least 3 clock cycles extra to access.
  170.  
  171. Aligning code is not necessary when you run on the Pentium, but for optimal
  172. performance on other processors you may align subroutine entries and loop
  173. entries by 16.
  174.  
  175.  
  176. 6. CACHE
  177. ========
  178. The Pentium without MMX has 8 kb of on-chip cache (level one cache) for
  179. code, and 8 kb for data. The Pentium with MMX has 16 kb for code and 16 kb
  180. for data. Data in the level 1 cache can be read or written to in just one
  181. clock cycle, whereas a cache miss may cost many clock cycles. It is
  182. therefore important that you understand how the cache works in order to use
  183. it most efficiently.
  184.  
  185. The data cache in the Pentium without MMX consists of 256 lines of 32 bytes
  186. each. Each time you read a data item which is not cached, the processor will
  187. read an entire cache line from memory. The cache lines are always aligned to
  188. a physical address divisible by 32. When you have read a byte at an address
  189. divisible by 32, then the next 31 bytes can be read or written to at almost
  190. no extra cost. You can take advantage of this by arranging data items which
  191. are used near each other together into aligned blocks of 32 bytes of memory.
  192. If, for example, you have a loop which accesses two arrays, then you may
  193. combine the two arrays into one array of structures, so that data which are
  194. used together are also stored together.
  195.  
  196. If the size of an array or other data structure is a multiple of 32 bytes,
  197. then you should preferably align it by 32.
  198.  
  199. A cache line can not be assigned to an arbitrary memory address. Each cache
  200. line has a 7-bit set-value which must match bit 5 through 11 of the physical
  201. RAM address (bit 0-4 define the 32 bytes within a cache line). There are two
  202. cache lines for each of the 128 set-values, so there are two possible cache
  203. lines to assign to any RAM address (four for the MMX version). The
  204. consequence of this is that the cache can hold no more than two different
  205. data blocks which have the same value in bits 5-11 of the address. You can
  206. determine if two addresses have the same set-value by the following method:
  207. Strip off the lower 5 bits of each address to get a value divisible by 32.
  208. If the difference between the two truncated addresses is a multiple of 4096
  209. (=1000H), then the addresses have the same set-value.
  210.  
  211. Let me illustrate this by the following piece of code, where ESI holds an
  212. address divisible by 32:
  213.  
  214. AGAIN:  MOV  EAX, [ESI]
  215.         MOV  EBX, [ESI + 13*4096 +  4]
  216.         MOV  ECX, [ESI + 20*4096 + 28]
  217.         DEC  EDX
  218.         JNZ  AGAIN
  219.  
  220. The three addresses used here all have the same set-value because the
  221. differences between the truncated addresses are multipla of 4096. This loop
  222. will perform very poorly. At the time you read ECX there is no free cache
  223. line with the proper set-value so the processor takes the least recently 
  224. used of the two possible cache lines, that is the one which was used for EAX,
  225. and fills it with the data from [ESI + 20*4096] to [ESI + 20*4096 + 31] and
  226. reads ECX.  Next, when reading EAX, you find that the cache line that held
  227. the value for EAX has now been discarded, so you take the least recently
  228. used line, which is the one holding the EBX value, and so on..  You have 
  229. nothing but cache misses and the loop takes something like 60 clock cycles.
  230. If the third line is changed to:
  231.  
  232.         MOV  ECX, [ESI + 20*4096 + 32]
  233.  
  234. then we have crossed a 32 byte boundary, so that we do not have the same
  235. set-value as in the first two lines, and there will be no problem assigning
  236. a cache line to each of the three addresses. The loop now takes only 3 clock
  237. cycles (except for the first time) - a very considerable improvement!
  238.  
  239. It may be very difficult to determine if your data addresses have the same 
  240. set-values, especially if they are scattered around in different segments.
  241. The best thing you can do to avoid problems of this kind is to keep all data 
  242. used in the critical part or your program within one contiguous block of 
  243. max.  8 kbytes or two contiguous blocks of max. 4 kbytes each (for example
  244. one block for static data and another block for data on the stack). This
  245. will make sure that your cache lines are used optimally.
  246.  
  247. If the critical part of your code accesses big data structures or random
  248. data addresses, then you may want to keep all frequently used variables
  249. (counters, pointers, control variables, etc.) within a single contiguous 
  250. block of max 4 kbytes so that you have a complete set of cache lines free
  251. for accessing random data. Since you probably need stack space anyway for
  252. subroutine parameters and return addresses, the best thing is to copy all 
  253. frequently used static data to dynamic variables on the stack, and copy
  254. them back again outside the critical loop if they have been changed.
  255.  
  256. Reading a data item which is not in the level one cache causes an entire
  257. cache line to be filled from the level two cache, which takes approximately
  258. 200 ns (that is 20 clocks on a 100 MHz system or 40 clocks on a 200 MHz
  259. system), but the bytes you ask for first are available already after 50-100
  260. ns. If the data item is not in the level two cache either, then you will
  261. get a delay of something like 200-300 ns. This delay will be somewhat longer
  262. if you cross a DRAM page boundary. (The size of a DRAM page is 1 kb for 4 MB
  263. 72 pin RAM modules, and 2 kb for 16 MB modules).
  264.  
  265. When you write to an address which is not in the level 1 cache, then the 
  266. value will go right through to the level 2 cache or to the RAM (depending on
  267. how the level 2 cache is set up). This takes approximately 100 ns. If you
  268. write eight or more times to the same 32 byte block of memory without also
  269. reading from it, and the block is not in the level one cache, then it may
  270. be advantageous to make a dummy read from the block first to load it into a
  271. cache line. All subsequent writes to the same block will then go to the
  272. cache instead, which takes only one clock cycle. (This is not needed on a
  273. PentiumPro, which always loads a cache line on write misses). There is
  274. sometimes a small penalty for writing repeatedly to the same address
  275. without reading in between.
  276.  
  277. Another way to reduce the number of write misses is to write 8 bytes at a
  278. time using  FILD / FISTP  with qword operands rather than writing 4 bytes at
  279. a time using integer registers. The extra cost of the slow FILD and FISTP
  280. instructions is compensated for by the fact that you only have to do half as
  281. many writes. However, this method is only advantageous on a Pentium, and
  282. only if the destination is not in the level 1 cache. The method is explained
  283. in section 19 below.
  284.  
  285. Temporary data may conveniently be stored at the stack because stack data
  286. are very likely to be in the cache. You should be aware, however, that if
  287. you store QWORD data on a DWORD size stack, or DWORD data on a WORD size
  288. stack, then you have a potential alignment problem.
  289.  
  290. If the life ranges of two data structures do not overlap, then they may use
  291. the same RAM area to increase cache efficiency. This is consistent with the
  292. common practice of allocating space for temporary variables on the stack.
  293.  
  294. Storing temporary data in registers is of course even more efficient. Since
  295. registers is a scarce ressource, you may want to use [ESP] rather than [EBP]
  296. for addressing data on the stack, in order to free EBP for other purposes.
  297. Just don't forget that the value of ESP changes every time you do a PUSH or 
  298. POP. (You cannot use ESP under 16-bit Windows because the timer interrupt 
  299. will modify the high word of ESP at unpredictable places in your code.)
  300.  
  301. The Pentium has a separate 8 kb cache for code, which is similar to the data
  302. cache. It is important that the critical part of your code (the innermost
  303. loops) fit in the code cache. Frequently used pieces of code or routines
  304. which are used together should preferable be stored near each other. Seldom
  305. used branches or procedures should go to the bottom of your code.
  306.  
  307.  
  308. 7. ADDRESS GENERATION INTERLOCK (AGI)
  309. =====================================
  310. It takes one clock cycle to calculate the address needed by an instruction
  311. which accesses memory. Normally, this calculation is done at a separate
  312. stage in the pipeline while the preceding instruction or instruction pair is
  313. executing. But if the address depends on the result of an instruction
  314. executing in the preceding clock cycle, then you have to wait an extra clock
  315. cycle for the address to be calculated. This is called an AGI stall.
  316.  
  317. Example:
  318. ADD EBX,4 / MOV EAX,[EBX]    ; AGI stall
  319. The stall in this example can be removed by putting some other instructions
  320. in between  ADD EBX,4  and  MOV EAX,[EBX]  or by rewriting the code to:
  321. MOV EAX,[EBX+4] / ADD EBX,4
  322.  
  323. You can also get an AGI stall with instructions which use ESP implicitly for
  324. addressing, such as PUSH, POP, CALL, and RET, if ESP has been changed in the
  325. preceding clock cycle by instructions such as MOV, ADD, or SUB. The Pentium
  326. has special circuitry to predict the value of ESP after a stack operation so
  327. that you do not get an AGI delay after changing ESP with PUSH, POP, or CALL.
  328. You can get an AGI stall after RET only if it has an immediate operand to
  329. add to ESP.
  330.  
  331. Examples:
  332. ADD ESP,4 / POP ESI            ; AGI stall
  333. POP EAX   / POP ESI            ; no stall, pair
  334. MOV ESP,EBP / RET              ; AGI stall
  335. CALL L1 / L1: MOV EAX,[ESP+8]  ; no stall
  336. RET / POP EAX                  ; no stall
  337. RET 8 / POP EAX                ; AGI stall
  338.  
  339. The LEA instruction is also subject to an AGI stall if it uses a base or
  340. index register which has been changed in the preceding clock cycle. Example:
  341. INC ESI / LEA EAX,[EBX+4*ESI]  ; AGI stall
  342.  
  343.  
  344. 8. PAIRING INTEGER INSTRUCTIONS
  345. ===============================
  346. The Pentium has two pipelines for executing instructions, called the U-pipe 
  347. and the V-pipe. Under certain conditions it is possible to execute two 
  348. instructions simultaneously, one in the U-pipe and one in the V-pipe. This 
  349. can almost double the speed. It is therefore advantageous to reorder your 
  350. instructions to make them pair.
  351.  
  352. The following instructions are pairable in either pipe:
  353.   MOV register, memory, or immediate into register or memory
  354.   PUSH register or immediate
  355.   POP register
  356.   LEA, NOP
  357.   INC, DEC, ADD, SUB, CMP, AND, OR, XOR,
  358.   and some forms of TEST (see section 17.3)
  359.  
  360. The following instructions are pairable in the U-pipe only:
  361. ADC, SBB
  362. SHR, SAR, SHL, SAL with immediate count
  363. ROR, ROL, RCR, RCL with an immediate count of 1
  364.  
  365. The following instructions can execute in either pipe but are only pairable
  366. when in the V-pipe: near call, short and near jump, short and near 
  367. conditional jump.
  368.  
  369. All other integer instructions can execute in the U-pipe only, and are not 
  370. pairable.
  371.  
  372. Two consecutive instructions will pair when the following conditions are met:
  373.  
  374. 8.1 The first instruction is pairable in the U-pipe and the second
  375.     instruction is pairable in the V-pipe.
  376.  
  377. 8.2 The second instruction cannot read or write a register which the first
  378.     instruction writes to. Examples:
  379.     MOV EAX, EBX / MOV ECX, EAX     ; read after write, do not pair
  380.     MOV EAX, 1   / MOV EAX, 2       ; write after write, do not pair
  381.     MOV EBX, EAX / MOV EAX, 2       ; write after read, pair OK
  382.     MOV EBX, EAX / MOV ECX, EAX     ; read after read, pair OK
  383.     MOV EBX, EAX / INC EAX          ; read and write after read, pair OK
  384.  
  385. 8.3 In rule 8.2 partial registers are treated as full registers. Example:
  386.     MOV AL, BL  /  MOV AH, 0        ; writes to different parts of the same
  387.                                     ; register, do not pair
  388.  
  389. 8.4 Two instructions which both write to parts of the flags register can
  390.     pair despite rule 8.2 and 8.3.  Example:
  391.     SHR EAX,4 / INC EBX   ; pair OK
  392.  
  393. 8.5 An instruction which writes to the flags can pair with a conditional
  394.     jump despite rule 8.2.  Example:
  395.     CMP EAX, 2 / JA LabelBigger   ; pair OK
  396.  
  397. 8.6 The following instruction combinations can pair despite the fact that
  398.     they both modify the stack pointer:
  399.     PUSH + PUSH,  PUSH + CALL,  POP + POP
  400.  
  401. 8.7 There are restrictions on the pairing of instructions with prefix.
  402.     There are several types of prefixes:
  403.     - instructions addressing a non-default segment have a segment prefix.
  404.     - instructions using 16 bit data in 32 bit mode, or 32 bit data in 16 bit
  405.       mode have an operand size prefix.
  406.     - instructions using 32 bit base or index registers in 16 bit mode have
  407.       an address size prefix.
  408.     - repeated string instructions have a repeat prefix.
  409.     - locked instructions have a LOCK prefix.
  410.     - many instructions which were not implemented on the 8086 processor
  411.       have a two byte opcode where the first byte is 0FH. The 0FH byte
  412.       behaves as a prefix on the Pentium without MMX, but not on the Pentium
  413.       with MMX. The most common instructions with 0FH prefix are: MOVZX,
  414.       MOVSX, PUSH FS, POP FS, PUSH GS, POP GS, LFS, LGS, LSS, SETcc, BT,
  415.       BTC, BTR, BTS, BSF, BSR, SHLD, SHRD, and IMUL with two operands and no
  416.       immediate operand.
  417.  
  418.     On the Pentium without MMX, a prefixed instruction can only execute in
  419.     the U-pipe, except for conditional near jumps.
  420.     On the Pentium with MMX, instructions with operand size, address
  421.     size, or 0FH prefix can execute in either pipe, whereas instructions with
  422.     segment, repeat, or lock prefix can only execute in the U-pipe.
  423.  
  424. 8.8 An instruction which has both a displacement and immediate data is not
  425.     pairable on the Pentium without MMX and only pairable in the U-pipe on
  426.     Pentium with MMX:
  427.     MOV DWORD PTR DS:[1000], 0    ; not pairable or only in U-pipe
  428.     CMP BYTE PTR [EBX+8], 1       ; not pairable or only in U-pipe
  429.     CMP BYTE PTR [EBX], 1         ; pairable
  430.     CMP BYTE PTR [EBX+8], AL      ; pairable
  431.     (Another problem with instructions which have both a displacement and
  432.     immediate data on the Pentium with MMX is that such instructions may
  433.     be longer than 7 bytes, which means that only one instruction can be
  434.     decoded per clock cycle, as explained in section 13.)
  435.  
  436. 8.9 Both instructions must be preloaded and decoded. This is explained in
  437.     section 9.
  438.  
  439. 8.10 There are special pairing rules for MMX instructions:
  440.     - MMX shift instructions can execute in either pipe but cannot pair with
  441.       other MMX shift instructions
  442.     - MMX multiply instructions can execute in either pipe but cannot pair
  443.       with other MMX multiply instructions. They take 3 clock cycles and
  444.       can be pipelined to a throughput of one multiplication per clock cycle
  445.       in the same way as floating point instructions (see chapter 15).
  446.     - an MMX instruction which accesses memory or integer registers can
  447.       execute only in the U-pipe and cannot pair with a non-MMX instruction.
  448.     for further details see the Intel manuals.
  449.  
  450.  
  451.  
  452. 9. FIRST TIME VERSUS REPEATED EXECUTION
  453. =======================================
  454. A piece of code usually takes much more time the first time it is executed
  455. than when it is repeated. The reasons are the following:
  456.  
  457. 9.1 Loading the code from RAM into the cache takes longer time than
  458.     executing it.
  459.  
  460. 9.2 In some cases decoding the code is the bottleneck. If it takes one clock
  461.     cycle to determine the length of an instruction, then it is not possible 
  462.     to decode two instructions per clock cycle, because the processor 
  463.     doesn't know where the second instruction begins. The Pentium solves 
  464.     this problem by remembering the length of any instruction which has 
  465.     remained in the cache since last time it was executed. As a consequence
  466.     of this, a set of instructions will not pair the first time they are 
  467.     executed, unless the first of the two instructions is only one byte 
  468.     long.
  469.  
  470. 9.3 Jump instructions will not be in the branch target buffer the first
  471.     time they execute, and therefore are less likely to be predicted
  472.     correctly. See chapter 12.
  473.  
  474. 9.4 Any data accessed by the code has to be loaded into the cache, which may
  475.     take much more time than executing the instructions. When the code is
  476.     repeated, then the data are more likely to be in the cache.
  477.  
  478. For these four reasons, a piece of code inside a loop will generally take
  479. much more time the first time it executes than the subsequent times.
  480.  
  481. If you have a big loop which doesn't fit into the code cache then you will
  482. get the penalty of 9.1 and 9.2 all the time because it doesn't run from the
  483. cache. You should therefore try to reorganize the loop to make it fit into 
  484. the cache.  
  485.  
  486. If you have many jumps and branches inside a loop, then you may get the
  487. penalty in 9.3 all the time.
  488.  
  489. Likewise, if a loop repeatedly accesses a data structure too big for
  490. the data cache, then you will get the penalty of data cache misses all the
  491. time.
  492.  
  493.  
  494. 10. IMPERFECT PAIRING
  495. =====================
  496. There are situations where the two instructions in a pair will not execute
  497. simultaneously, or only partially overlap in time. They should still be
  498. considered a pair, though, because the first instruction executes in the
  499. U-pipe, and the second in the V-pipe. No subsequent instruction can start
  500. to execute before both instructions in the imperfect pair have finished.
  501.  
  502. Imperfect pairing will happen in the following cases:
  503.  
  504. 10.1 If the second instructions suffers an AGI stall (see chapter 7).
  505.  
  506. 10.2 Two instructions cannot access the same dword of memory simultaneously.
  507.      The following examples assume that ESI is divisible by 4:
  508.      MOV AL, [ESI] / MOV BL, [ESI+1]
  509.      The two operands are within the same dword, so they cannot execute
  510.      simultaneously. The pair takes 2 clock cycles.
  511.      MOV AL, [ESI+3] / MOV BL, [ESI+4]
  512.      Here the two operands are on each side of a dword boundary, so they
  513.      pair perfectly, and take only one clock cycle.
  514.  
  515. 10.3 Rule 10.2 is extended to the case where bit 2-4 is the same in the two
  516.      addresses (cache bank conflict). For dword addresses this means that
  517.      the difference between the two addresses should not be divisible by 32.
  518.      Examples:
  519.      MOV [ESI], EAX / MOV [ESI+32000], EBX ;  imperfect pairing
  520.      MOV [ESI], EAX / MOV [ESI+32004], EBX ;  perfect pairing
  521.  
  522. Pairable instructions which do not access memory take one clock cycle to
  523. execute, except for mispredicted jumps. MOV instructions to or from memory
  524. also take only one clock cycle if the data area is in the cache and properly
  525. aligned. There is no speed penalty for using complex addressing modes such
  526. as scaled index registers.
  527.  
  528. A pairable instruction which reads from memory, does some calculation, and
  529. stores the result in a register or flags, takes 2 clock cycles.
  530. (read/modify instructions).
  531.  
  532. A pairable instruction which reads from memory, does some calculation, and
  533. writes the result back to the memory, takes 3 clock cycles.
  534. (read/modify/write instructions).
  535.  
  536. 10.4 If a read/modify/write instruction is paired with a read/modify or
  537.      read/modify/write instruction, then they will pair imperfectly.
  538.  
  539. The number of clock cycles used is given in the following table:
  540.  
  541.                       |             First instruction
  542.                       | MOV or             read/       read/modify/
  543. Second instruction    | register only      modify      write
  544. ----------------------|----------------------------------------------
  545. MOV or register only  |      1               2              3
  546. read/modify           |      2               2              4
  547. read/modify/write     |      3               3              5
  548. ----------------------|-----------------------------------------------
  549.  
  550. Example:
  551. ADD [mem1], EAX / ADD EBX, [mem2]  ; 4 clock cycles
  552. ADD EBX, [mem2] / ADD [mem1], EAX  ; 3 clock cycles
  553.  
  554. 10.5 When two paired instructions both take extra time due to cache misses,
  555.      misalignment, or jump misprediction, then the pair will take more time
  556.      than each instruction, but less than the sum of the two.
  557.  
  558. In order to avoid imperfect pairing you have to know which instructions go
  559. into the U-pipe, and which to the V-pipe. You can find out this by looking
  560. backwards in your code and search for instructions which are unpairable,
  561. pairable only in one of the pipes, or cannot pair due to one of the rules
  562. in chapter 8.
  563.  
  564. Imperfect pairing can often be avoided by reordering your instructions.
  565. Example:
  566.  
  567. L1:     MOV     EAX,[ESI]
  568.         MOV     EBX,[ESI]
  569.         INC     ECX
  570.  
  571. Here the two MOV instructions form an imperfect pair because they both
  572. access the same memory location, and the sequence takes 3 clock cycles.
  573. You can improve the code by reordering the instructions so that  INC ECX
  574. pairs with one of the MOV instructions.
  575.  
  576. L2:     MOV     EAX,OFFSET [A]
  577.         XOR     EBX,EBX
  578.         INC     EBX
  579.         MOV     ECX,[EAX]
  580.         JMP     L1
  581.  
  582. The pair  INC EBX / MOV ECX,[EAX]  is imperfect because the latter
  583. instruction has an AGI stall. The sequence takes 4 clocks. If you insert
  584. a NOP or any other instruction so that  MOV ECX,[EAX] pairs with  JMP L1
  585. instead, then the sequence takes only 3 clocks.
  586.  
  587. The next example is in 16 bit mode, assuming that SP is divisible by 4:
  588.  
  589. L3:     PUSH    AX
  590.         PUSH    BX
  591.         PUSH    CX
  592.         PUSH    DX
  593.         CALL    FUNC
  594.  
  595. Here the PUSH instructions form two imperfect pairs, because both operands
  596. in each pair go into the same dword of memory. PUSH BX could possibly pair
  597. perfectly with PUSH CX (because they go on each side of a dword boundary)
  598. but it doesn't because it has already been paired with PUSH AX. The sequence
  599. therefore takes 5 clocks. If you insert a NOP or any other instruction so
  600. that PUSH BX pairs with PUSH CX, and PUSH DX with CALL FUNC, then the
  601. sequence will take only 3 clocks. Another way to solve the problem is to
  602. make sure that SP is not divisible by 4. Knowing whether SP is divisible by
  603. 4 or not in 16 bit mode can be difficult, so the best way to avoid this
  604. problem is to use 32 bit mode.
  605.  
  606.  
  607. 11. SPLITTING COMPLEX INSTRUCTIONS INTO SIMPLER ONES
  608. ====================================================
  609. You may split up read/modify and read/modify/write instructions to improve
  610. pairing. Example:
  611. ADD [mem1],EAX / ADD [mem2],EBX    ; 5 clock cycles
  612. This code may be split up into a sequence which takes only 3 clock cycles:
  613. MOV ECX,[mem1] / MOV EDX,[mem2] / ADD ECX,EAX / ADD EDX,EBX
  614. MOV [mem1],ECX / MOV [mem2],EDX
  615.  
  616. Likewise you may split up non-pairable instructions into pairable instructions:
  617. PUSH [mem1] / PUSH [mem2]  ; non-pairable
  618. Split up into:
  619. MOV EAX,[mem1] / MOV EBX,[mem2] / PUSH EAX / PUSH EBX  ; everything pairs
  620.  
  621. Other examples of non-pairable instructions which may be split up into simpler
  622. pairable instructions:
  623. CDQ  split into:  MOV EDX,EAX / SAR EDX,31
  624. NOT EAX  change to  XOR EAX,-1
  625. NEG EAX  split into  XOR EAX,-1 / INC EAX
  626. MOVZX EAX,BYTE PTR [mem]  split into  XOR EAX,EAX / MOV AL,BYTE PTR [mem]
  627. JECXZ  split into  TEST ECX,ECX / JZ
  628. LOOP   split into  DEC ECX / JNZ
  629. XLAT   change to   MOV AL,[EBX+EAX]
  630.  
  631. If splitting instructions doesn't improve speed, then you may keep the
  632. complex or nonpairable instructions in order to reduce code size.
  633.  
  634.  
  635. 12. JUMPS AND BRANCHES
  636. ======================
  637. Note: This chapter describes in detail the branch prediction mechanism of
  638. the Pentium without MMX. This information is based on research done by me
  639. and Karki Jitendra Bahadur. Information found in Intel documents and
  640. elsewhere on this subject is directly misleading, and following the
  641. advises given is such documents is likely to lead to sub-optimal code.
  642.  
  643. In the following, I will use the term 'jump instruction' for any
  644. instruction which can change the instruction pointer, including
  645. conditional and unconditional, direct and indirect, near and far, jumps,
  646. calls, and returns.
  647.  
  648. The Pentium attempts to predict where a jump will go to, and whether a
  649. conditional jump will be taken or fall through. If the prediction is correct,
  650. then it can save time by loading the subsequent instructions into the
  651. pipeline before the jump is executed. If the prediction turns out to be
  652. wrong, then the pipeline has to be flushed, which will cost a penalty of 3
  653. to 5 clock cycles. (4 for a conditional jump in the V-pipe, 3 in all other
  654. cases for the Pentium without MMX. The MMX version has penalties of 5 resp.
  655. 4 clocks.)
  656.  
  657. When optimizing code, it is important to minimize the number of misprediction
  658. penalties. This requires a good understanding of how the jump prediction
  659. works. I am giving a very detailed description of this topic here, because
  660. this information is not published anywhere else.
  661.  
  662. Note that the following description applies only to the Pentium without
  663. MMX. Branch prediction in later processors will only be covered briefly.
  664.  
  665.  
  666. Branch prediction
  667. -----------------
  668. The Pentium uses a 'branch target buffer' (BTB), which can save information
  669. for up to 256 jump instructions. The BTB is organized like a 4-way set-
  670. associative cache with 64 entries per way. This means that the BTB can hold
  671. no more than 4 entries with the same set value. Unlike the data cache, the
  672. BTB uses a pseudo random replacement algorithm, which means that a new entry
  673. will not necessarily displace the least recently used entry of the same set-
  674. value. How the set-value is calculated will be explained later. Each BTB
  675. entry stores the address of the jump target and a prediction state, which
  676. can have four different values:
  677.  
  678. state 0: "strongly not taken"
  679. state 1: "weakly not taken"
  680. state 2: "weakly taken"
  681. state 3: "strongly taken"
  682.  
  683. A branch instruction is predicted to jump when in state 2 or 3, and to
  684. fall through when in state 0 or 1. Some documents do - not quite correctly -
  685. describe the state transition so that the state is incremented when the
  686. branch is taken, and decremented when it falls through (no wrap around).
  687. This would provide quite a good prediction, because a branch instruction
  688. would have to deviate twice from what it does most of the time, before the
  689. prediction changes.
  690.  
  691. However, this mechanism has been compromised by the fact that state
  692. 0 also means 'unused BTB entry'. So a BTB entry in state 0 is the same as
  693. no BTB entry. This makes sense, because a branch instruction is predicted
  694. to fall through if it has no BTB entry. This improves the utilization of
  695. the BTB, because a branch instruction which is seldom taken will most of
  696. the time not take up any BTB entry.
  697.  
  698. Now, if a jumping instruction has no BTB entry, then a new BTB entry will
  699. be generated, and this new entry will always be set to state 3. This means
  700. that it is impossible to go from state 0 to state 1 (except for a very
  701. special case discussed later). From state 0 you can only go to state 3, if
  702. the branch is taken. If the branch falls through, then it will stay out of
  703. the BTB.
  704.  
  705. This is a serious design flaw. By always setting new entries to state
  706. 3, the designers apparently have given priority to minimizing the first
  707. time penalty for unconditional jumps and branches often taken, rather than
  708. improving the prediction of conditional jumps in tight innermost loops,
  709. which is almost the only place where speed really matters. The consequence
  710. of this flaw is, that a branch instruction which falls through most of the
  711. time will have up to three times as many mispredictions as a branch
  712. instruction which is taken most of the time.
  713.  
  714. You may take this asymmetry into account by organizing your branches so
  715. that they are taken more often than not.
  716.  
  717. Consider for example this if-then-else construction:
  718.  
  719.         TEST EAX,EAX
  720.         JZ   A
  721.         <branch 1>
  722.         JMP  E
  723. A:      <branch 2>
  724. E:
  725.  
  726. If branch 1 is executed more often than branch 2, and branch 2 is seldom
  727. executed twice in succession, then you can reduce the number of branch
  728. mispredictions by up to a factor 3 by swapping the two branches so that
  729. the branch instruction will jump more often than fall through:
  730.  
  731.         TEST EAX,EAX
  732.         JNZ  A
  733.         <branch 2>
  734.         JMP  E
  735. A:      <branch 1>
  736. E:
  737.  
  738. (This is _contrary_ to the recommendations in Intel's tutorial. They don't
  739. seem to recognize the asymmetry in branch prediction. But it is easy to
  740. prove that the latter example is superior).
  741.  
  742. There may be reasons to put the most often executed branch first, however:
  743. 1. Putting seldom executed branches away in the bottom of your code can
  744.    improve code cache utilization.
  745. 2. A branch instruction seldom taken will stay out of the BTB most of the
  746.    time, possibly improving BTB utilization.
  747. 3. The branch instruction will be predicted as not taken if it has been
  748.    flushed out of the BTB by other branch instructions.
  749. 4. The asymmetry in branch prediction only exists on the Pentium without MMX (?)
  750.  
  751. These considerations have little weight, however, for small critical loops,
  752. so I would still recommend organizing branches with a skewed distribution
  753. so that the branch instruction is taken more often than not, unless branch
  754. 2 is executed so seldom, that misprediction doesn't matter.
  755.  
  756. Likewise, you should preferably organize loops with the testing branch at
  757. the bottom, as in this example:
  758.  
  759.         MOV ECX, [N]
  760. L:      MOV [EDI],EAX
  761.         ADD EDI,4
  762.         DEC ECX
  763.         JNZ L
  764.  
  765. If N is high, then the JNZ instruction here will be taken more often than
  766. not, and never fall through twice in succession.
  767.  
  768.  
  769. BTB is looking ahead
  770. --------------------
  771. The BTB mechanism is counting instruction pairs, rather than single
  772. instructions, so you have to know how instructions are pairing in order
  773. to analyze where a BTB entry is stored. The BTB entry for any jump
  774. instruction is attached to the address of the U-pipe instruction in the
  775. preceding instruction pair. (An unpaired instruction counts as one pair).
  776. Example:
  777.  
  778.         SHR EAX,1
  779.         MOV EBX,[ESI]
  780.         CMP EAX,EBX
  781.         JB  L
  782.  
  783. Here  SHR  pairs with  MOV,  and  CMP  pairs with  JB. The BTB entry for
  784. JB L  is thus attached to the address of the SHR EAX,1 instruction. When
  785. this BTB entry is met, and if it is in state 2 or 3, then the Pentium will
  786. read the target address from the BTB entry, and load the instructions
  787. following L into the pipeline. This happens before the branch instruction
  788. has been decoded, so the Pentium relies solely on the information in the
  789. BTB when doing this.
  790.  
  791. You may remember, that instructions are seldom pairing the first time they
  792. are executed (see paragraph 9.2). If the instructions above are not
  793. pairing, then the BTB entry should be attached to the address of the CMP
  794. instruction, and this entry would be wrong on the next execution, when
  795. instructions are pairing. However, in most cases the Pentium is smart enough
  796. to not make a BTB entry when there is an unused pairing opportunity, so you
  797. don't get a BTB entry until the second execution, and hence you won't get a
  798. prediction until the third execution. (In the rare case, where every second
  799. instruction is a single-byte instruction, you may get a BTB entry on the
  800. first execution which becomes invalid in the second execution, but since
  801. the instruction it is attached to will then go to the V-pipe, it is ignored
  802. and gives no penalty. A BTB entry is only read if it is attached to the
  803. address of a U-pipe instruction).
  804.  
  805. A BTB entry is identified by its set-value which is equal to bits 0-5
  806. of the address it is attached to. Bits 6-31 are then stored in the BTB as
  807. a tag. Addresses which are spaced a multiple of 64 bytes apart will have
  808. the same set-value. You can have no more than four BTB entries with the
  809. same set-value. If you want to check whether your jump instructions contend
  810. for the same BTB entries, then you have to compare bits 0-5 of the addresses
  811. of the U-pipe instructions in the preceding instruction pairs. This is very
  812. tedious, and I have never heard of anybody doing so. There are no tools
  813. available to do this job for you, as far as I know.
  814.  
  815.  
  816. Consecutive branches
  817. --------------------
  818. When a jump is mispredicted, then the pipeline gets flushed. If the next
  819. instruction pair executed also contains a jump instruction, then the Pentium
  820. won't load its target because it cannot load a new target while the
  821. pipeline is being flushed. The result is that the second jump instruction
  822. is predicted to fall through regardless of the state of its BTB entry.
  823. Therefore, if the second jump is also taken, then you will get another
  824. penalty. The state of the BTB entry for the second jump instruction does get
  825. correctly updated, though. If you have a long chain of taken jump
  826. instructions, and the first jump in the chain is mispredicted, then the
  827. pipeline will get flushed all the time, and you will get nothing but
  828. mispredictions until you meet an instruction pair that does not jump. The
  829. most extreme case of this is a loop which jumps to itself: It will get a
  830. misprediction penalty for each iteration.
  831.  
  832. This is not the only problem with consecutive jumps. Another problem is that
  833. you can have a branch instruction between a BTB entry and the jump
  834. instruction it belongs to. If the first branch instruction jumps to
  835. somewhere else, then strange things may happen. Consider this example:
  836.  
  837.         SHR EAX,1
  838.         MOV EBX,[ESI]
  839.         CMP EAX,EBX
  840.         JB  L1
  841.         JMP L2
  842.  
  843. L1:     MOV EAX,EBX
  844.         INC EBX
  845.  
  846. When  JB L1  falls through, then you will get a BTB entry for  JMP L2
  847. attached to the address of  CMP EAX,EBX.  But what will happen when
  848. JB L1  later is taken?  At the time when the BTB entry for  JMP L2  is
  849. read, the processor doesn't know that the next instruction pair does not
  850. contain a jump instruction, so it will actually predict the instruction
  851. pair  MOV EAX,EBX / INC EBX  to jump to L2.  The penalty for predicting
  852. non-jump instructions to jump is 3 clock cycles.  The BTB entry for  JMP L2
  853. will get its state decremented, because it is applied to something which
  854. doesn't jump.  If we keep going to L1, then the BTB entry for  JMP L2
  855. will be decremented to state 1 and 0, so that the problem will disappear
  856. until next time  JMP L2  is executed.
  857.  
  858. The penalty for predicting the non-jumping instructions to jump only occurs
  859. when the jump to L1 is predicted. In the case that  JB L1  is mispredictedly
  860. jumping, then the pipeline gets flushed and we won't get the false L2 target
  861. loaded, so in this case we will not see the penalty of predicting the
  862. non-jumping instructions to jump, but we do get the BTB entry for  JMP L2
  863. decremented.
  864.  
  865. Suppose, now, that we replace the  INC EBX  instruction above with another
  866. jump instruction.  This third jump instruction will then use the same
  867. BTB entry as  JMP L2  with the possible penalty of predicting a wrong target,
  868. (unless it happens to also have L2 as target).
  869.  
  870. To summarize, consecutive jumps can lead to the following problems:
  871. - failure to load a jump target when the pipeline is being flushed by a
  872.   preceding mispredicted jump.
  873. - a BTB entry being mis-applied to non-jumping instructions and predicting
  874.   them to jump.
  875. - a second consequence of the above is that a mis-applied BTB entry will
  876.   get its state decremented, possibly leading to a later misprediction of
  877.   the jump it belongs to. Even unconditional jumps can be predicted to fall
  878.   through for this reason.
  879. - two jump instructions may share the same BTB entry, leading to the
  880.   prediction of a wrong target.
  881.  
  882. All this mess may give you a lot of penalties, so you should definitely
  883. avoid having an instruction pair containing a jump immediately after another
  884. poorly predictable jump.
  885.  
  886. It is time for an illustrative example:
  887.  
  888.         CALL P
  889.         TEST EAX,EAX
  890.         JZ   L2
  891. L1:     MOV  [EDI],EBX
  892.         ADD  EDI,4
  893.         DEC  EAX
  894.         JNZ  L1
  895. L2:     CALL P
  896.  
  897. This looks like a quite nice and normal piece of code: A function call,
  898. a loop which is bypassed when the count is zero, and another function call.
  899. How many problems can you spot in this program?
  900.  
  901. First, we may note that the function P is called alternatingly from two
  902. different locations. This means that the target for the return from P will
  903. be changing all the time. Consequently, the return from P will always be
  904. mispredicted.
  905.  
  906. Assume, now, that EAX is zero. The jump to L2 will not have its target
  907. loaded because the mispredicted return caused a pipeline flush. Next, the
  908. second  CALL P  will also fail to have its target loaded because  JZ L2
  909. caused a pipeline flush. Here we have the situation where a chain of
  910. consecutive jumps makes the pipeline flush repeatedly because the first
  911. jump was mispredicted. The BTB entry for  JZ L2  is stored at the address
  912. of P's return instruction. This BTB entry will now be mis-applied to
  913. whatever comes after the second  CALL P,  but that doesn't give a penalty
  914. because the pipeline is flushed by the mispredicted second return.
  915.  
  916. Now, let's see what happens if EAX has a nonzero value the next time:
  917. JZ L2  is always predicted to fall through because of the flush. The second
  918. CALL P  has a BTB entry at the address of  TEST EAX,EAX.  This entry will
  919. be mis-applied to the  MOV/ADD  pair, predicting it to jump to P. This
  920. causes a flush which prevents  JNZ L1  from loading its target. If we have
  921. been here before, then the second  CALL P  will have another BTB entry at
  922. the address of  DEC EAX.  On the second and third iteration of the loop, this
  923. entry will also be mis-applied to the  MOV/ADD  pair, until it has had its
  924. state decremented to 1 or 0. This will not cause a penalty on the second
  925. iteration because the flush from  JNZ L1  prevents it from loading its false
  926. target, but on the third iteration it will. The subsequent iterations of the
  927. loop have no penalties, but when it exits,  JNZ L1  is mispredicted. The
  928. flush would now prevent  CALL P  from loading its target, were it not for
  929. the fact that the BTB entry for  CALL P  has already been destroyed by
  930. being mis-applied several times.
  931.  
  932. We can improve this code by putting in some NOP's to separate all consecutive
  933. jumps:
  934.  
  935.         CALL P
  936.         TEST EAX,EAX
  937.         NOP
  938.         JZ   L2
  939. L1:     MOV  [EDI],EBX
  940.         ADD  EDI,4
  941.         DEC  EAX
  942.         JNZ  L1
  943. L2:     NOP
  944.         NOP
  945.         CALL P
  946.  
  947. The extra NOP's cost 2 clock cycles, but they save much more. Furthermore,
  948. JZ L2  is now moved to the U-pipe which reduces its penalty from 4 to 3
  949. when mispredicted. The only problem that remains is that the returns from
  950. P are always mispredicted. This problem can only be solved by replacing the
  951. call to P by an inline macro (if you have enough code cache).
  952.  
  953. The lesson to learn from this example is that you should always look
  954. carefully for consecutive jumps and see if you can save time by inserting
  955. some NOP's. You should be particularly aware of those situations where
  956. misprediction is unavoidable, such as loop exits and returns from procedures
  957. which are called from varying locations. If you have something useful to
  958. put in, in stead of the NOP's, then you should of course do so.
  959.  
  960. Multiway branches (case statements) may be implemented either as a tree of
  961. branch instructions or as a list of jump addresses. If you choose to use
  962. a tree of branch instructions, then you have to include some NOP's or other
  963. instructions to separate the consecutive branches. A list of jump addresses
  964. may therefore be a better solution on the Pentium. The list of jump
  965. addresses should be placed in the data segment. Never put data in the code
  966. segment! On the PentiumPro you may choose the branch tree solution if it
  967. gives a better prediction.
  968.  
  969.  
  970. Multiple BTB entries
  971. --------------------
  972. While two jump instructions can share the same BTB entry, one jump
  973. instruction can also have multiple BTB entries if it is jumped to from
  974. different locations, or if its pairing is changing. Example:
  975.  
  976.         JZ  L1
  977.         MOV EAX,1
  978. L1:     MOV EBX,2
  979.         MOV ECX,3
  980.         JC  L2
  981.  
  982. If  JZ L1  falls through, then  MOV EAX,1  pairs with  MOV EBX,2, and
  983. MOV ECX,3  pairs with  JC L2.  The BTB entry for  JC L2  will be attached
  984. to the address of  MOV EAX,1. When  JZ L1  is taken, then  MOV EBX,2 will
  985. pair with  MOV ECX,3,  JC L2  will be unpaired, and its BTB entry will be
  986. at  MOV EBX,2.  So you have two BTB entries for  JC L2.  The first entry
  987. is used when the zero flag is clear, the other when set.  This may actually
  988. be an advantage, because it will improve the predictability of the second
  989. branch instruction if there is a correllation between the two.  Assume, for
  990. example, that this code sequence is preceded by a  CMP  instruction. Then
  991. we can be certain that the zero flag and the carry flag will never both be
  992. set at the same time. We will get no second BTB entry for  JC L2  at
  993. MOV EBX,2  because it always falls through if the zero flag is set, and
  994. we will never get a misprediction for  JC L2  when  JZ L1  is taken.
  995. The situations where you can take advantage of this trick are rare,
  996. however, because you might as well let L1 go to another branch which
  997. doesn't test the carry flag at all.
  998.  
  999.  
  1000. Tight loops
  1001. -----------
  1002. In a small loop you will often access the same BTB entry repeatedly with
  1003. small intervals. This never causes a stall. Rather than waiting for a BTB
  1004. entry to be updated, the Pentium somehow bypasses the pipeline and gets the
  1005. resulting state from the last jump before it has been written to the BTB.
  1006. This mechanism is almost transparent to the user, but it does in some cases
  1007. have funny effects: You can see a branch prediction going from state 0 to
  1008. state 1, rather than to state 3, if the zero has not yet been written to the
  1009. BTB. This happens if the loop has no more than four instruction pairs. In
  1010. loops with only two instruction pairs you may sometimes have state 0 for two
  1011. consecutive iterations without going out of the BTB. In such small loops it
  1012. also happens in rare cases that the prediction uses the state resulting from
  1013. two iterations ago, rather than from the last iteration. These funny effects
  1014. will usually not have any negative effects on performance.
  1015.  
  1016.  
  1017. Avoiding branches
  1018. -----------------
  1019. Sometimes it is possible to obtain the same effect as a branch by ingenious
  1020. manipulation of bits and flags. For example you may calculate the absoulte
  1021. value of a signed number without branching:
  1022.         MOV EDX,EAX
  1023.         SAR EDX,31
  1024.         XOR EAX,EDX
  1025.         SUB EAX,EDX
  1026.  
  1027. The carry flag is particularly useful for this kind of tricks.
  1028. Setting carry if a value is zero:  CMP [value],1
  1029. Setting carry if a value is not zero:  XOR EAX,EAX  /  CMP EAX,[value]
  1030. Incrementing a counter if carry:  ADC EAX,0
  1031. Setting a bit for each time the carry is set:  RCL EAX,1
  1032. Generating a bit mask if carry is set:  SBB EAX,EAX
  1033.  
  1034. This example finds the minimum of two unsigned numbers: if (b < a)  a = b;
  1035.         SUB EBX,EAX
  1036.         SBB ECX,ECX
  1037.         AND ECX,EBX
  1038.         ADD EAX,ECX
  1039.  
  1040. This example chooses between two numbers:  if (a != 0)  a = b;  else a = c;
  1041.         CMP EAX,1
  1042.         SBB EAX,EAX
  1043.         XOR ECX,EBX
  1044.         AND EAX,ECX
  1045.         XOR EAX,EBX
  1046.  
  1047. Whether or not such tricks are worth the extra code depend on how
  1048. predictable a conditional jump would be, whether the extra pairing
  1049. opportunities of the branch-free code can be utilized, and whether there
  1050. are other jumps following immediately after which could suffer the penalties
  1051. of consecutive jumps.
  1052.  
  1053.  
  1054. Later processors
  1055. ----------------
  1056. The PentiumPro and MMX processors have a more advanced branch prediction
  1057. mechanism which enable them to correctly predict a simple repetitive
  1058. pattern. They do not have the asymmetry flaw that the Pentium without MMX
  1059. has. A conditional jump, which has not been seen before, is predicted
  1060. taken if it goes backwards (e.g. a loop), and not taken if it goes
  1061. forward, on these new processors.
  1062.  
  1063. MMX processors have a return stack buffer (RSB) which remembers where
  1064. calls come from, so you will no longer get mispredictions when calling
  1065. a subroutine from varying locations. To make this mechanism work, you
  1066. should always match calls with returns. This means that you should not
  1067. use the return instruction as an indirect jump or use an indirect jump
  1068. as return.
  1069.  
  1070. Mispredictions are very expensive on the PentiumPro (10-16 clocks!). You
  1071. should therefore avoid poorly predictable branches, and replace them with
  1072. conditional moves whenever possible.
  1073.  
  1074. The new processors also have problems with consecutive jumps, but for
  1075. different reasons. So avoiding consecutive jumps may be desirable on all
  1076. processors.
  1077.  
  1078.  
  1079. 13. PREFIXES
  1080. ============
  1081. An instruction with one or more prefixes may not be able to execute in the
  1082. V-pipe (se paragraph 8.7), and it may take more than one clock cycle to
  1083. decode. On the Pentium without MMX, the decoding delay is one clock cycle
  1084. for each prefix except for the 0Fh prefix of conditional near jumps.
  1085.  
  1086. The Pentium with MMX has no decoding delay for 0Fh prefix. Segment and repeat
  1087. prefixes take one clock extra to decode. Address and operand size prefixes
  1088. take two clocks extra to decode (one for reading the prefix, and one for
  1089. calculating the length of the instruction).
  1090.  
  1091. Address size prefixes can be avoided by using 32 bit mode.
  1092. Segment prefixes can be avoided in 32 bit mode by using a flat memory model.
  1093. Operand size prefixes can be avoided in 32 bit mode by using only 8 bit and
  1094. 32 bit integers.
  1095.  
  1096. Where prefixes are unavoidable, the decoding delay may be masked if a
  1097. preceding instruction takes more than one clock cycle to execute. The rule
  1098. for the Pentium without MMX is that any instruction which takes N clock
  1099. cycles to execute (not to decode) can 'overshadow' the decoding delay of N-1
  1100. prefixes in the next two (sometimes three) instructions or instruction
  1101. pairs. In other words, each extra clock cycle that an instruction takes to
  1102. execute can be used to decode one prefix in a later instruction. This
  1103. shadowing effect even extends across a predicted branch. Any instruction
  1104. which takes more than one clock cycle to execute, and any instruction which
  1105. is delayed because of an AGI stall, cache miss, misalignment, or any other
  1106. reason except decoding delay and branch misprediction, has a shadowing 
  1107. effect.
  1108.  
  1109. The Pentium with MMX has a similar shadowing effect, but the mechanism is
  1110. different. Decoded instructions are stored in a transparent
  1111. first-in-first-out (FIFO) buffer, which can hold up to four instructions.
  1112. As long as there are instructions in the FIFO buffer you get no delay.
  1113. When the buffer is empty then instructions are executed as soon as they
  1114. are decoded. The buffer is filled when instructions are decoded faster
  1115. than they are executed, i.e. when you have unpaired or multi-cycle
  1116. instructions. The FIFO buffer is emptied when instructions execute faster
  1117. than they are decoded, i.e. when you have decoding delays due to prefixes.
  1118. The FIFO buffer is empty after a mispredicted branch. The FIFO buffer can
  1119. receive two instructions per clock cycle provided that the second
  1120. instruction is without prefixes and none of the instructions are longer
  1121. than 7 bytes. The two execution pipelines (U and V) can each receive one
  1122. instruction per clock cycle from the FIFO buffer.
  1123.  
  1124.  
  1125. Examples:
  1126.  
  1127. CLD / REP MOVSD
  1128. The CLD instruction takes two clock cycles and can therefore overshadow
  1129. the decoding delay of the REP prefix. The code would take one clock cycle
  1130. more if the CLD instruction was placed far from the REP MOVSD.
  1131.  
  1132. CMP DWORD PTR [EBX],0 / MOV EAX,0 / SETNZ AL
  1133. The CMP instruction takes two clock cycles here because it is a read/modify
  1134. instruction. The 0FH prefix of the SETNZ instruction is decoded during the 
  1135. second clock cycle of the CMP instruction, so that the decoding delay is
  1136. hidden.
  1137.  
  1138.  
  1139. 14. REDUCING CODE SIZE
  1140. ======================
  1141. As explained in paragraph 6, the code cache is 8 kb. If you have problems
  1142. keeping the critical parts of your code within the code cache, then you may
  1143. consider reducing the size of your code.
  1144.  
  1145. 32 bit code is usually bigger than 16 bit code because addresses and data
  1146. constants take 4 bytes in 32 bit code and only 2 bytes in 16 bit code.
  1147. However, 16 bit code has other penalties such as prefixes and problems with
  1148. accessing adjacent words simultaneously (see chapter 10). Some other
  1149. methods for reducing the size or your code are discussed below.
  1150.  
  1151. Both jump addresses, data addresses, and data constants take less space if
  1152. they can be expressed as a sign-extended byte, i.e. if they are within the
  1153. interval from -128 to +127.
  1154.  
  1155. For jump addresses this means that short jumps take two bytes of code,
  1156. whereas jumps beyond 127 bytes take 5 bytes if unconditional and 6 bytes if
  1157. conditional.
  1158.  
  1159. Likewise, data addresses take less space if they can be expressed as a
  1160. pointer and a displacement between -128 and +127.
  1161. Example:
  1162. MOV EBX,DS:[100000] / ADD EBX,DS:[100004]          ; 12 bytes
  1163. Reduce to:
  1164. MOV EAX,100000 / MOV EBX,[EAX] / ADD EBX,[EAX+4]   ; 10 bytes
  1165.  
  1166. The advantage of using a pointer obviously increases if you use it many
  1167. times. Storing data on the stack and using EBP or ESP as pointer will thus
  1168. make your code smaller than if you use static memory locations and absolute
  1169. addresses, provided of course that your data are within 127 bytes of the
  1170. pointer. Using PUSH and POP to write and read temporary data is even more
  1171. advantageous.
  1172.  
  1173. Data constants may also take less space if they are between -128 and +127.
  1174. Most instructions with immediate operands have a short form where the
  1175. operand is a sign-extended single byte. Examples:
  1176. PUSH 200      ; 5 bytes
  1177. PUSH 100      ; 2 bytes
  1178.  
  1179. ADD EBX,128   ; 6 bytes
  1180. SUB EBX,-128  ; 3 bytes
  1181.  
  1182. The most important instruction with an immediate operand which doesn't have
  1183. such a short form is MOV. Examples:
  1184. MOV EAX, 1              ; 5 bytes
  1185. XOR EAX,EAX / INC EAX   ; 3 bytes
  1186. PUSH 1 / POP EAX        ; 3 bytes
  1187.  
  1188. If the same constant is used more than once then you may of course load it
  1189. into a register. Example:
  1190. MOV DWORD PTR [EBX],0 / MOV DWORD PTR [EBX+4],0   ; 13 bytes
  1191. XOR EAX,EAX / MOV [EBX],EAX / MOV [EBX+4],EAX     ;  7 bytes
  1192.  
  1193. You may also consider that different instructions have different lengths.
  1194. The following instructions take only one byte and are therefore very
  1195. attractive: PUSH reg, POP reg, INC reg32, DEC reg32.
  1196. INC and DEC with 8 bit registers take 2 bytes, so  INC EAX  is shorter than
  1197. INC AL.
  1198.  
  1199. XCHG EAX,reg is also a single-byte instruction and thus takes less space 
  1200. than MOV EAX,reg, but it is slower and not pairable.
  1201.  
  1202. Some instructions take one byte less when they use the accumulator than when
  1203. they use any other register. Examples:
  1204.  
  1205. MOV EAX,DS:[100000]  is smaller than  MOV EBX,DS:[100000]
  1206. ADD EAX,1000         is smaller than  ADD EBX,1000
  1207.  
  1208. Instructions with pointers take one byte less when they have only a base 
  1209. pointer (not ESP) and a displacement than when they have a scaled index 
  1210. register, or both base pointer and index register, or ESP as base pointer. 
  1211. Examples: 
  1212. MOV EAX,[array][EBX]  is smaller than  MOV EAX,[array][EBX*4]
  1213. MOV EAX,[EBP+12]      is smaller than  MOV EAX,[ESP+12]
  1214. Instructions with EBP as base pointer and no displacement and no index take
  1215. one byte more than with other registers: 
  1216. MOV EAX,[EBX]    is smaller than  MOV EAX,[EBP],  but
  1217. MOV EAX,[EBX+4]  is same size as  MOV EAX,[EBP+4].  
  1218.  
  1219.  
  1220. 15. SCHEDULING FLOATING POINT CODE
  1221. ==================================
  1222. Floating point instructions cannot pair the way integer instructions can, 
  1223. except for one special case, defined by the following rules:
  1224.  
  1225. - the first instruction (executing in the U-pipe) must be FLD, FADD, FSUB, 
  1226.   FMUL, FDIV, FCOM, FCHS, or FABS
  1227.  
  1228. - the second instruction (in V-pipe) must be FXCH
  1229.  
  1230. - the instruction following the FXCH must be a floating point instruction,
  1231.   otherwise the FXCH will take an extra clock cycle.
  1232.  
  1233. This special pairing is important, as will be explained shortly.
  1234.  
  1235. While floating point instructions in general cannot be paired, many can be 
  1236. pipelined, i.e. one instruction can begin before the previous instruction has 
  1237. finished. Example:
  1238.  
  1239. FADD ST(1),ST(0)   ; clock cycle 1-3
  1240. FADD ST(2),ST(0)   ; clock cycle 2-4
  1241. FADD ST(3),ST(0)   ; clock cycle 3-5
  1242. FADD ST(4),ST(0)   ; clock cycle 4-6
  1243.  
  1244. Obviously, two instructions cannot overlap if the second instruction needs
  1245. the result of the first. Since almost all floating point instructions
  1246. involve the top of stack register, ST(0), there are seemingly not very many
  1247. possibilities for making an instruction independent of the result of
  1248. previous instructions. The solution to this problem is register renaming.
  1249. The FXCH instruction does not in reality swap the contents of two registers,
  1250. it only swaps their names. Instructions which push or pop the register
  1251. stack also work by renaming. Register renaming has been highly optimized on
  1252. the Pentium so that a register may be renamed while in use. Register
  1253. renaming never causes stalls - it is even possible to rename a register more
  1254. than once in the same clock cycle, as for example when you pair FLD or
  1255. FCOMPP with FXCH.
  1256.  
  1257. By the proper use of FXCH instructions you may obtain a lot of overlapping in
  1258. your floating point code. Example:
  1259.  
  1260. FLD     [a1]    ; clock cycle 1
  1261. FADD    [a2]    ; clock cycle 2-4
  1262. FLD     [b1]    ; clock cycle 3
  1263. FADD    [b2]    ; clock cycle 4-6
  1264. FLD     [c1]    ; clock cycle 5
  1265. FADD    [c2]    ; clock cycle 6-8
  1266. FXCH    ST(2)   ; clock cycle 6
  1267. FADD    [a3]    ; clock cycle 7-9
  1268. FXCH    ST(1)   ; clock cycle 7
  1269. FADD    [b3]    ; clock cycle 8-10
  1270. FXCH    ST(2)   ; clock cycle 8
  1271. FADD    [c3]    ; clock cycle 9-11
  1272. FXCH    ST(1)   ; clock cycle 9
  1273. FADD    [a4]    ; clock cycle 10-12
  1274. FXCH    ST(2)   ; clock cycle 10
  1275. FADD    [b4]    ; clock cycle 11-13
  1276. FXCH    ST(1)   ; clock cycle 11
  1277. FADD    [c4]    ; clock cycle 12-14
  1278. FXCH    ST(2)   ; clock cycle 12
  1279.  
  1280. In the above example we are interleaving three independent threads. Each
  1281. FADD takes 3 clock cycles, and we can start a new FADD in each clock cycle.
  1282. When we have started an FADD in the 'a' thread we have time to start two new
  1283. FADD instructions in the 'b' and 'c' threads before returning to the 'a'
  1284. thread, so every third FADD belongs to the same thread. We are using FXCH
  1285. instructions every time to get the register that belongs to the desired
  1286. thread into ST(0). As you can see in the example above, this generates a
  1287. regular pattern, but note well that the FXCH instructions repeat with a
  1288. period of two while the threads have a period of three. This can be quite
  1289. confusing, so you have to 'play computer' in order to know which registers
  1290. are where.
  1291.  
  1292. All versions of the instructions FADD, FSUB, FMUL, and FILD take 3 clock
  1293. cycles and are able to overlap, so that these instructions may be scheduled
  1294. using the method described above. Using a memory operand does not take more
  1295. time than a register operand if the memory operand is in the level 1 cache
  1296. and properly aligned.
  1297.  
  1298. By now you must be used to the rules having exceptions, and the overlapping
  1299. rule is no exception: You cannot start an FMUL instruction one clock cycle 
  1300. after another FMUL instruction, because the FMUL circuitry is not perfectly 
  1301. pipelined. It is recommended that you put another instruction in between two 
  1302. FMUL's. Example:
  1303.  
  1304. FLD     [a1]    ; clock cycle 1
  1305. FLD     [b1]    ; clock cycle 2
  1306. FLD     [c1]    ; clock cycle 3
  1307. FXCH    ST(2)   ; clock cycle 3
  1308. FMUL    [a2]    ; clock cycle 4-6
  1309. FXCH            ; clock cycle 4
  1310. FMUL    [b2]    ; clock cycle 5-7    (stall)
  1311. FXCH    ST(2)   ; clock cycle 5
  1312. FMUL    [c2]    ; clock cycle 7-9    (stall)
  1313. FXCH            ; clock cycle 7
  1314. FSTP    [a3]    ; clock cycle 8-9
  1315. FXCH            ; clock cycle 10     (unpaired)
  1316. FSTP    [b3]    ; clock cycle 11-12
  1317. FSTP    [c3]    ; clock cycle 13-14
  1318.  
  1319. Here you have a stall before  FMUL [b2]  and before  FMUL [c2]  because 
  1320. another FMUL started in the preceding clock cycle. You can improve this code 
  1321. by putting FLD instructions in between the FMUL's:
  1322.  
  1323. FLD     [a1]    ; clock cycle 1
  1324. FMUL    [a2]    ; clock cycle 2-4
  1325. FLD     [b1]    ; clock cycle 3
  1326. FMUL    [b2]    ; clock cycle 4-6
  1327. FLD     [c1]    ; clock cycle 5
  1328. FMUL    [c2]    ; clock cycle 6-8
  1329. FXCH    ST(2)   ; clock cycle 6
  1330. FSTP    [a3]    ; clock cycle 7-8
  1331. FSTP    [b3]    ; clock cycle 9-10
  1332. FSTP    [c3]    ; clock cycle 11-12
  1333.  
  1334. In other cases you may put FADD, FSUB, or anything else in between FMUL's to
  1335. avoid the stalls.
  1336.  
  1337. Overlapping floating point instructions requires of course that you have 
  1338. some independent threads that you can interleave. If you have only one big 
  1339. formula to execute, then you may compute parts of the formula in parallel to 
  1340. achieve overlapping. If, for example, you want to add six numbers, then you 
  1341. may split the operations into two threads with three numbers in each, and
  1342. add the two threads in the end: 
  1343.  
  1344. FLD     [a]     ; clock cycle 1
  1345. FADD    [b]     ; clock cycle 2-4
  1346. FLD     [c]     ; clock cycle 3
  1347. FADD    [d]     ; clock cycle 4-6
  1348. FXCH            ; clock cycle 4
  1349. FADD    [e]     ; clock cycle 5-7
  1350. FXCH            ; clock cycle 5
  1351. FADD    [f]     ; clock cycle 7-9    (stall)
  1352. FADD            ; clock cycle 10-12  (stall)
  1353.  
  1354. Here we have a one clock stall before  FADD [f]  because it is waiting for
  1355. the result of  FADD [d]  and a two clock stall before the last FADD because 
  1356. it is waiting for the result of  FADD [f]. The latter stall can be hidden by 
  1357. filling in some integer instructions, but the first stall can not because an 
  1358. integer instruction at this place would make the FXCH unpairable.  
  1359.  
  1360. The first stall can be avoided by having three threads rather than two, but 
  1361. that would cost an extra FLD so we do not save anything by having three
  1362. threads rather than two unless there are at least eight numbers to add.  
  1363.  
  1364. Not all floating point instructions can overlap. And some floating point 
  1365. instructions can overlap more subsequent integer instructions than 
  1366. subsequent floating point instructions. The FDIV instruction, for example,
  1367. takes 39 clock cycles. All but the first clock cycle can overlap with
  1368. integer instructions, but only the last two clock cycles can overlap with 
  1369. floating point instructions. Example: 
  1370.  
  1371. FDIV            ; clock cycle 1-39
  1372. FXCH            ; clock cycle 1-2
  1373. CMC             ; clock cycle 3-4
  1374. RCR EAX,1       ; clock cycle 5
  1375. INC EBX         ; clock cycle 5
  1376. FADD [x]        ; clock cycle 38-40
  1377. FXCH            ; clock cycle 38
  1378. FMUL [y]        ; clock cycle 40-42
  1379.  
  1380. The first FXCH pairs with the FDIV, but takes an extra clock cycle because
  1381. it is not followed by a floating point instruction. The CMC starts before 
  1382. the FDIV is finished, but has to wait for the FXCH to finish. The RCR and
  1383. INC instructions are pairing. The FADD has to wait till clock 38 because new
  1384. floating point instructions can only execute during the last two clock
  1385. cycles of the FDIV. The second FXCH pairs with the FADD. The FMUL has to
  1386. wait for the FDIV to finish because it uses the result of the division.
  1387.  
  1388. If you have nothing else to put in after a floating point instruction with a
  1389. large integer overlap, such as FDIV or FSQRT, then you may put in a dummy
  1390. read from an address which you expect to need later in the program to make
  1391. sure it is in the level one cache. Example:
  1392.         FDIV    QWORD PTR [EBX]
  1393.         CMP     [ESI],EAX
  1394.         FMUL    QWORD PTR [ESI]
  1395. Here we use the integer overlap to pre-load the value at [ESI] into the
  1396. cache while the FDIV is being computed (we don't care what the result of the
  1397. CMP is).
  1398.  
  1399. Paragraph 21 gives a complete listing of floating point instructions, and
  1400. what they can pair or overlap with.
  1401.  
  1402. One floating point instruction requires special mentioning, namely FST or
  1403. FSTP with a memory operand. This instruction takes two clock cycles in the
  1404. execution stage, but it seems to start converting the value in ST(0) already
  1405. at the address decode stage in the pipeline, so that there is a one clock 
  1406. stall if the value to store is not ready one clock cycle in advance. This is 
  1407. analogous to an AGI stall. Example: 
  1408.  
  1409. FLD     [a1]    ; clock cycle 1
  1410. FADD    [a2]    ; clock cycle 2-4
  1411. FLD     [b1]    ; clock cycle 3
  1412. FADD    [b2]    ; clock cycle 4-6
  1413. FXCH            ; clock cycle 4
  1414. FSTP    [a3]    ; clock cycle 6-7
  1415. FSTP    [b3]    ; clock cycle 8-9
  1416.  
  1417. The  FSTP [a3]  stalls for one clock cycle because the result of  FADD [a2]  
  1418. is not ready in the preceding clock cycle. In many cases you cannot hide 
  1419. this type of stall without scheduling your floating point code into four 
  1420. threads or putting some integer instructions in between. No other 
  1421. instructions have this weirdness. The two clock cycles in the execution 
  1422. stage of the FST(P) instruction cannot pair or overlap with any subsequent 
  1423. instructions.  
  1424.  
  1425. Instructions with integer operands such as FIADD, FISUB, FIMUL, FIDIV, FICOM 
  1426. may be split up into simpler operations in order to improve overlapping. 
  1427. Example:
  1428.  
  1429. FILD    [a]     ; clock cycle 1-3
  1430. FIMUL   [b]     ; clock cycle 4-9
  1431.  
  1432. Split up into:
  1433.  
  1434. FILD    [a]     ; clock cycle 1-3
  1435. FILD    [b]     ; clock cycle 2-4
  1436. FMUL            ; clock cycle 5-7
  1437.  
  1438. In this example, you save two clocks by overlapping the two FILD instructions.
  1439.  
  1440.  
  1441. 16. Loop Optimation
  1442. ===================
  1443. When analyzing a program you often find that 99% of the time consumption
  1444. lies in the innermost loop. The way to improve the speed is to carefully
  1445. optimize the most time-consuming loop using ASM language. The rest of the 
  1446. program may be left in high-level language.  
  1447.  
  1448. A loop generally contains a counter controlling how many times to iterate,
  1449. and often array access reading or writing one array element for each 
  1450. iteration. I have chosen as example a procedure which reads integers from an 
  1451. array, changes the sign of each integer, and stores the results in another
  1452. array.  
  1453.  
  1454. A C language code for this procedure would be:
  1455.  
  1456. void ChangeSign (int * A, int * B, int N) {
  1457.   int i;
  1458.   for (i=0; i<N; i++) B[i] = -A[i];}
  1459.  
  1460. Translating to assembler, we might write the procedure like this: 
  1461.  
  1462. Example 1:
  1463.  
  1464. _ChangeSign PROCEDURE NEAR
  1465.         PUSH    ESI
  1466.         PUSH    EDI
  1467. A       EQU     DWORD PTR [ESP+12]
  1468. B       EQU     DWORD PTR [ESP+16]
  1469. N       EQU     DWORD PTR [ESP+20]
  1470.  
  1471.         MOV     ECX, [N]
  1472.         JECXZ   L2
  1473.         MOV     ESI, [A]
  1474.         MOV     EDI, [B]
  1475.         CLD
  1476. L1:     LODSD
  1477.         NEG     EAX
  1478.         STOSD
  1479.         LOOP    L1
  1480. L2:     POP     EDI
  1481.         POP     ESI
  1482.         RET                     ; (no extra pop if C calling convention)
  1483. _ChangeSign     ENDP
  1484.  
  1485. This looks like a nice solution, but it is not optimal because it uses slow 
  1486. non-pairable instructions. It takes 11 clock cycles per iteration if all
  1487. data are in the level one cache.  
  1488.  
  1489. Using pairable instructions only
  1490. --------------------------------
  1491.  
  1492. Example 2:
  1493.  
  1494.         MOV     ECX, [N]
  1495.         MOV     ESI, [A]
  1496.         TEST    ECX, ECX
  1497.         JZ      SHORT L2
  1498.         MOV     EDI, [B]
  1499. L1:     MOV     EAX, [ESI]       ; u
  1500.         XOR     EBX, EBX         ; v (pairs)
  1501.         ADD     ESI, 4           ; u
  1502.         SUB     EBX, EAX         ; v (pairs)
  1503.         MOV     [EDI], EBX       ; u
  1504.         ADD     EDI, 4           ; v (pairs)
  1505.         DEC     ECX              ; u
  1506.         JNZ     L1               ; v (pairs)
  1507. L2:
  1508.  
  1509. Here we have used pairable instructions only, and scheduled the instruc-
  1510. tions so that everything pairs. It now takes only 4 clock cycles per 
  1511. iteration. We could have obtained the same speed without splitting the NEG
  1512. instruction, but the other unpairable instructions should be split up.  
  1513.  
  1514. Using the same register for counter and index
  1515. ---------------------------------------------
  1516.  
  1517. Example 3:
  1518.  
  1519.         MOV     ESI, [A]
  1520.         MOV     EDI, [B]
  1521.         MOV     ECX, [N]
  1522.         XOR     EDX, EDX
  1523.         TEST    ECX, ECX
  1524.         JZ      SHORT L2
  1525. L1:     MOV     EAX, [ESI+4*EDX]          ; u
  1526.         NEG     EAX                       ; u
  1527.         MOV     [EDI+4*EDX], EAX          ; u
  1528.         INC     EDX                       ; v (pairs)
  1529.         CMP     EDX, ECX                  ; u
  1530.         JB      L1                        ; v (pairs)
  1531. L2:
  1532.  
  1533. Using the same register for counter and index gives us fewer instructions in 
  1534. the body of the loop, but it still takes 4 clocks because we have two 
  1535. unpaired instructions.
  1536.  
  1537. Letting the counter end at zero
  1538. -------------------------------
  1539. We want to get rid of the CMP instruction in example 3 by letting the 
  1540. counter end at zero and use the zero flag for detecting when we are finished 
  1541. as we did in example 2. One way to do this would be to execute the loop 
  1542. backwards taking the last array elements first. However, data caches are 
  1543. optimized for accessing data forwards, not backwards, so if cache misses are
  1544. likely, then you should rather start the counter at -N and count through 
  1545. negative values up to zero. The base registers should then point to the end 
  1546. of the arrays rather than the beginning: 
  1547.  
  1548. Example 4:
  1549.  
  1550.         MOV     ESI, [A]
  1551.         MOV     EAX, [N]
  1552.         MOV     EDI, [B]
  1553.         XOR     ECX, ECX
  1554.         LEA     ESI, [ESI+4*EAX]          ; point to end of array A
  1555.         SUB     ECX, EAX                  ; -N
  1556.         LEA     EDI, [EDI+4*EAX]          ; point to end of array B
  1557.         JZ      SHORT L2
  1558. L1:     MOV     EAX, [ESI+4*ECX]          ; u
  1559.         NEG     EAX                       ; u
  1560.         MOV     [EDI+4*ECX], EAX          ; u
  1561.         INC     ECX                       ; v (pairs)
  1562.         JNZ     L1                        ; u
  1563. L2:
  1564.  
  1565. We are now down at five instructions in the loop body but it still takes 4 
  1566. clocks because of poor pairing. (If the addresses and sizes of the arrays 
  1567. are constants we may save two registers by substituting A+SIZE A for ESI and 
  1568. B+SIZE B for EDI). Now let's see how we can improve pairing.  
  1569.  
  1570. Pairing calculations with loop overhead
  1571. ---------------------------------------
  1572. We may want to improve pairing by intermingling calculations with the loop
  1573. control instructions. If we want to put something in between INC ECX and
  1574. JNZ L1, it has to be something that doesn't affect the zero flag. The  MOV
  1575. [EDI+4*ECX],EBX  instruction after  INC ECX  would generate an AGI delay,
  1576. so we have to be more ingenious:
  1577.  
  1578. Example 5:
  1579.  
  1580.         MOV     EAX, [N]
  1581.         XOR     ECX, ECX
  1582.         SHL     EAX, 2                    ; 4 * N
  1583.         JZ      SHORT L3
  1584.         MOV     ESI, [A]
  1585.         MOV     EDI, [B]
  1586.         SUB     ECX, EAX                  ; - 4 * N
  1587.         ADD     ESI, EAX                  ; point to end of array A
  1588.         ADD     EDI, EAX                  ; point to end of array B
  1589.         JMP     SHORT L2
  1590. L1:     MOV     [EDI+ECX-4], EAX          ; u
  1591. L2:     MOV     EAX, [ESI+ECX]            ; v (pairs)
  1592.         XOR     EAX, -1                   ; u
  1593.         ADD     ECX, 4                    ; v (pairs)
  1594.         INC     EAX                       ; u
  1595.         JNC     L1                        ; v (pairs)
  1596.         MOV     [EDI+ECX-4], EAX
  1597. L3:
  1598.  
  1599. I have used a different way to calculate the negative of EAX here: inverting 
  1600. all bits and adding one. The reason why I am using this method is that I can 
  1601. use a dirty trick with the INC instruction: INC doesn't change the carry 
  1602. flag, whereas ADD does. I am using ADD rather than INC to increment my loop 
  1603. counter and testing the carry flag rather than the zero flag. It is then 
  1604. possible to put the INC EAX in between without affecting the carry flag. You 
  1605. may think that we could have used  LEA EAX,[EAX+1]  here instead of
  1606. INC EAX,  at least that doesn't change any flags, but the LEA instruction
  1607. would have an AGI stall so that's not the best solution.  
  1608.  
  1609. I have obtained perfect pairing here and the loop now takes only 3 clock 
  1610. cycles. Whether you want to increment the loop counter by 1 (as in example 
  1611. 4) or by 4 (as in example 5) is a matter of taste, it makes no difference
  1612. in loop timing.
  1613.  
  1614. Overlapping the end of one operation with the beginning of the next
  1615. -------------------------------------------------------------------
  1616. The method used in example 5 is not very generally applicable so we may look 
  1617. for other methods of improving pairing opportunities. One way is to 
  1618. reorganize the loop so that the end of one operation overlaps with the
  1619. beginning of the next. I will call this convoluting the loop. A convoluted
  1620. loop has an unfinished operation at the end of each loop iteration which 
  1621. will be finished in the next run. Actually, example 5 did pair the last MOV 
  1622. of one iteration with the first MOV of the next, but we want to explore this 
  1623. method further: 
  1624.  
  1625. Example 6:
  1626.  
  1627.         MOV     ESI, [A]
  1628.         MOV     EAX, [N]
  1629.         MOV     EDI, [B]
  1630.         XOR     ECX, ECX
  1631.         LEA     ESI, [ESI+4*EAX]          ; point to end of array A
  1632.         SUB     ECX, EAX                  ; -N
  1633.         LEA     EDI, [EDI+4*EAX]          ; point to end of array B
  1634.         JZ      SHORT L3
  1635.         XOR     EBX, EBX
  1636.         MOV     EAX, [ESI+4*ECX]
  1637.         INC     ECX
  1638.         JZ      SHORT L2
  1639. L1:     SUB     EBX, EAX                  ; u
  1640.         MOV     EAX, [ESI+4*ECX]          ; v (pairs)
  1641.         MOV     [EDI+4*ECX-4], EBX        ; u
  1642.         INC     ECX                       ; v (pairs)
  1643.         MOV     EBX, 0                    ; u
  1644.         JNZ     L1                        ; v (pairs)
  1645. L2:     SUB     EBX, EAX
  1646.         MOV     [EDI+4*ECX-4], EBX
  1647. L3:
  1648.  
  1649. Here we begin reading the second value before we have stored the first, and 
  1650. this of course improves pairing opportunities. The MOV EBX,0 instruction 
  1651. has been put in between INC ECX and JNZ L1 not to improve pairing but to
  1652. avoid AGI stall.
  1653.  
  1654. Rolling out a loop
  1655. ------------------
  1656. The most generally applicable way to improve pairing opportunities is to do 
  1657. two operations for each run and do half as many runs. This is called rolling 
  1658. out a loop:
  1659.  
  1660. Example 7:
  1661.  
  1662.         MOV     ESI, [A]
  1663.         MOV     EAX, [N]
  1664.         MOV     EDI, [B]
  1665.         XOR     ECX, ECX
  1666.         LEA     ESI, [ESI+4*EAX]          ; point to end of array A
  1667.         SUB     ECX, EAX                  ; -N
  1668.         LEA     EDI, [EDI+4*EAX]          ; point to end of array B
  1669.         JZ      SHORT L2
  1670.         TEST    AL,1                      ; test if N is odd
  1671.         JZ      SHORT L1
  1672.         MOV     EAX, [ESI+4*ECX]          ; N is odd. do the odd one
  1673.         NEG     EAX
  1674.         MOV     [EDI+4*ECX], EAX
  1675.         INC     ECX                       ; make counter even
  1676.         JZ      SHORT L2                  ; N = 1
  1677. L1:     MOV     EAX, [ESI+4*ECX]          ; u
  1678.         MOV     EBX, [ESI+4*ECX+4]        ; v (pairs)
  1679.         NEG     EAX                       ; u
  1680.         NEG     EBX                       ; u
  1681.         MOV     [EDI+4*ECX], EAX          ; u
  1682.         MOV     [EDI+4*ECX+4], EBX        ; v (pairs)
  1683.         ADD     ECX, 2                    ; u
  1684.         JNZ     L1                        ; v (pairs)
  1685. L2:
  1686.  
  1687. Now we are doing two operations in parallel which gives the best pairing
  1688. opportunities. We have to test if N is odd and if so do one operation
  1689. outside the loop because the loop can only do an even number of operations.
  1690.  
  1691. The loop has an AGI stall at the first MOV instruction because ECX has been
  1692. incremented in the preceding clock cycle. The loop therefore takes 6 clock
  1693. cycles for two operations.
  1694.  
  1695. Reorganizing a loop to remove AGI stall
  1696. ---------------------------------------
  1697. Example 8:
  1698.  
  1699.         MOV     ESI, [A]
  1700.         MOV     EAX, [N]
  1701.         MOV     EDI, [B]
  1702.         XOR     ECX, ECX
  1703.         LEA     ESI, [ESI+4*EAX]          ; point to end of array A
  1704.         SUB     ECX, EAX                  ; -N
  1705.         LEA     EDI, [EDI+4*EAX]          ; point to end of array B
  1706.         JZ      SHORT L3
  1707.         TEST    AL,1                      ; test if N is odd
  1708.         JZ      SHORT L2
  1709.         MOV     EAX, [ESI+4*ECX]          ; N is odd. do the odd one
  1710.         NEG     EAX                       ; no pairing opportunity
  1711.         MOV     [EDI+4*ECX-4], EAX
  1712.         INC     ECX                       ; make counter even
  1713.         JNZ     SHORT L2
  1714.         NOP                               ; add NOP's if JNZ L2 not predictable
  1715.         NOP
  1716.         JMP     SHORT L3                  ; N = 1
  1717. L1:     NEG     EAX                       ; u
  1718.         NEG     EBX                       ; u
  1719.         MOV     [EDI+4*ECX-8], EAX        ; u
  1720.         MOV     [EDI+4*ECX-4], EBX        ; v (pairs)
  1721. L2:     MOV     EAX, [ESI+4*ECX]          ; u
  1722.         MOV     EBX, [ESI+4*ECX+4]        ; v (pairs)
  1723.         ADD     ECX, 2                    ; u
  1724.         JNZ     L1                        ; v (pairs)
  1725.         NEG     EAX
  1726.         NEG     EBX
  1727.         MOV     [EDI+4*ECX-8], EAX
  1728.         MOV     [EDI+4*ECX-4], EBX
  1729. L3:
  1730.  
  1731. The trick is to find a pair of instructions that do not use the loop counter
  1732. as index and reorganize the loop so that the counter is incremented in the 
  1733. preceding clock cycle. We are now down at 5 clock cycles for two operations 
  1734. which is close to the best possible.  
  1735.  
  1736. If data caching is critical, then you may improve the speed further by 
  1737. combining the A and B arrays into one structured array so that each B[i] 
  1738. comes immediately after the corresponding A[i]. If the structured array is 
  1739. aligned by at least 8 then B[i] will always be in the same cache line as 
  1740. A[i], so you will never have a cache miss when writing B[i]. This may of 
  1741. course have a tradeoff in other parts of the program so you have to weigh 
  1742. the costs against the benefits.
  1743.  
  1744.  
  1745. Rolling out by more than 2
  1746. --------------------------
  1747. You may think of doing more than two operations per iteration in order to 
  1748. reduce the loop overhead per operation. But since the loop overhead in most 
  1749. cases can be reduced to only one clock cycle per iteration, then rolling out 
  1750. the loop by 4 rather than by 2 would only save 1/4 clock cycle per 
  1751. operation, which is hardly worth the effort. Only if the loop overhead cannot
  1752. be reduced to one clock cycle and if N is very big, should you think of 
  1753. unrolling by 4.
  1754.  
  1755. The drawbacks of excessive loop unrolling are: 
  1756. 1.  You need to calculate N MODULO R, where R is the unrolling factor, and 
  1757.     do N MODULO R operations before or after the main loop in order to make 
  1758.     the remaining number of operations divisible by R. This takes a lot of 
  1759.     extra code and poorly predictable branches. And the loop body of course 
  1760.     also becomes bigger.  
  1761. 2.  A Piece of code usually takes much more time the first time it executes, 
  1762.     and the penalty of first time execution is bigger the more code you 
  1763.     have, especially if N is small.  
  1764. 3.  Excessive code size makes the utilization of the code cache less 
  1765.     effective.
  1766.  
  1767. Handling multiple 8 or 16 bit operands simultaneously in 32 bit registers
  1768. -------------------------------------------------------------------------
  1769. If you need to manipulate arrays of 8 or 16 bit operands, then there is a
  1770. problem with unrolled loops because you may not be able to pair two memory 
  1771. access operations. For example  MOV AL,[ESI] / MOV BL,[ESI+1]  will not pair
  1772. if the two operands are within the same dword of memory. But there may be a 
  1773. much smarter method, namely to handle four bytes at a time in the same 32 
  1774. bit register.  
  1775.  
  1776. The following example adds 2 to all elements of an array of bytes:
  1777.  
  1778. Example 9:
  1779.  
  1780.         MOV     ESI, [A]         ; address of byte array
  1781.         MOV     ECX, [N]         ; number of elements in byte array
  1782.         TEST    ECX, ECX         ; test if N is 0
  1783.         JZ      SHORT L2
  1784.         MOV     EAX, [ESI]       ; read first four bytes
  1785. L1:     MOV     EBX, EAX         ; copy into EBX
  1786.         AND     EAX, 7F7F7F7FH   ; get lower 7 bits of each byte in EAX
  1787.         XOR     EBX, EAX         ; get the highest bit of each byte in EBX
  1788.         ADD     EAX, 02020202H   ; add desired value to all four bytes
  1789.         XOR     EBX, EAX         ; combine bits again
  1790.         MOV     EAX, [ESI+4]     ; read next four bytes
  1791.         MOV     [ESI], EBX       ; store result
  1792.         ADD     ESI, 4           ; increment pointer
  1793.         SUB     ECX, 4           ; decrement loop counter
  1794.         JA      L1               ; loop
  1795. L2:
  1796.  
  1797. This loop takes 5 clock cycles for every 4 bytes. The array should of course 
  1798. be aligned by 4. If the number of elements in the array is not divisible by 
  1799. four, then you may pad it in the end with a few extra bytes to make the 
  1800. length divisible by four. This loop will always read past the end of the 
  1801. array, so you should make sure the array is not placed at the end of a 
  1802. segment to avoid a general protection error.  
  1803.  
  1804. Note that I have masked out the highest bit of each byte to avoid a possible 
  1805. carry from each byte into the next when adding. I am using XOR rather than 
  1806. ADD when putting in the high bit again to avoid carry.  
  1807.  
  1808. The  ADD ESI,4  instruction could have been avoided by using the loop 
  1809. counter as index as in example 4. However, this would give an odd number of 
  1810. instructions in the loop body, so there would be one unpaired instruction 
  1811. and the loop would still take 5 clocks. Making the branch instruction
  1812. unpaired would save one clock after the last operation when the branch is 
  1813. mispredicted, but we would have to spend an extra clock cycle in the prolog 
  1814. code to setup a pointer to the end of the array and calculate -N, so the two 
  1815. methods will be exactly equally fast. The method presented here is the 
  1816. simplest and shortest.  
  1817.  
  1818. The next example finds the length of a zero-terminated string by searching 
  1819. for the first byte of zero. It is faster than using REP SCASB: 
  1820.  
  1821. Example 10:
  1822.  
  1823. STRLEN  PROC    NEAR
  1824.         MOV     EAX,[ESP+4]               ; get pointer
  1825.         MOV     EDX,7
  1826.         ADD     EDX,EAX                   ; pointer+7 used in the end
  1827.         PUSH    EBX
  1828.         MOV     EBX,[EAX]                 ; read first 4 bytes
  1829.         ADD     EAX,4                     ; increment pointer
  1830. L1:     LEA     ECX,[EBX-01010101H]       ; subtract 1 from each byte
  1831.         XOR     EBX,-1                    ; invert all bytes
  1832.         AND     ECX,EBX                   ; and these two
  1833.         MOV     EBX,[EAX]                 ; read next 4 bytes
  1834.         ADD     EAX,4                     ; increment pointer
  1835.         AND     ECX,80808080H             ; test all sign bits
  1836.         JZ      L1                        ; no zero bytes, continue loop
  1837.         TEST    ECX,00008080H             ; test first two bytes
  1838.         JNZ     SHORT L2
  1839.         SHR     ECX,16                    ; not in the first 2 bytes
  1840.         ADD     EAX,2
  1841. L2:     SHL     CL,1                      ; use carry flag to avoid a branch
  1842.         POP     EBX
  1843.         SBB     EAX,EDX                   ; compute length
  1844.         RET                               ; (or RET 4 if pascal)
  1845. STRLEN  ENDP
  1846.  
  1847. Again we have used the method of overlapping the end of one operation with 
  1848. the beginning of the next to improve pairing. I have not unrolled the loop 
  1849. because it is likely to repeat relatively few times. The string should of 
  1850. course be aligned by 4. The code will always read past the end of the 
  1851. string, so the string should not be placed at the end of a segment.
  1852.  
  1853. The loop body has an odd number of instructions so there is one unpaired.  
  1854. Making the branch instruction unpaired rather than one of the other 
  1855. instructions has the advantage that it saves 1 clock cycle when the branch 
  1856. is mispredicted.
  1857.  
  1858. The  TEST ECX,00008080H  instruction is non-pairable. You could use the 
  1859. pairable instruction  OR CH,CL  here instead, but then you would have to
  1860. put in a NOP or something to avoid the penalties of consequtive branches.
  1861. Another problem with  OR CH,CL  is that it would cause a partial register
  1862. stall on a 486 or PentiumPro processor. So I have chosen to keep the
  1863. unpairable TEST instruction.
  1864.  
  1865. Handling 4 bytes simultaneously can be quite difficult. The code uses a
  1866. formula which generates a nonzero value for a byte if, and only if, the
  1867. byte is zero. This makes it possible to test all four bytes in one 
  1868. operation. This algorithm involves the subtraction of 1 from all bytes (in 
  1869. the LEA instruction). I have not masked out the highest bit of each byte
  1870. before subtracting, as I did in the previous example, so the subtraction may
  1871. generate a borrow to the next byte, but only if it is zero, and this is 
  1872. exactly the situation where we don't care what the next byte is, because we 
  1873. are searching forwards for the first zero. If we were searching backwards 
  1874. then we would have to re-read the dword after detecting a zero, and then 
  1875. test all four bytes to find the last zero, or use BSWAP to reverse the order 
  1876. of the bytes.  
  1877.  
  1878. If you want to search for a byte value other than zero, then you may XOR all 
  1879. four bytes with the value you are searching for, and then use the method 
  1880. above to search for zero.  
  1881.  
  1882. Handling multiple operands in the same register is easier on the MMX 
  1883. processors because they have special instructions and special 64 bit 
  1884. registers for this purpose. Using the MMX instructions has a high penalty if 
  1885. you are using floating point instructions shortly afterwards, so there may 
  1886. still be situations where you want to use 32 bit registers as in the 
  1887. examples above.  
  1888.  
  1889.  
  1890. Loops with floating point operations
  1891. ------------------------------------
  1892. The methods of optimizing floating point loops are basically the same as for
  1893. integer loops, although the floating point instructions are overlapping 
  1894. rather than pairing.  
  1895.  
  1896. Consider the C language code:
  1897.  
  1898.   int i, n;  double * X;  double * Y;  double DA;
  1899.   for (i=0; i<n; i++)  Y[i] = Y[i] - DA * X[i];
  1900.  
  1901. This piece of code (called DAXPY) has been studied extensively because it is 
  1902. the key to solving linear equations.  
  1903.  
  1904. Example 11:
  1905.  
  1906. DSIZE   = 8                                      ; data size
  1907.         MOV     EAX, [N]                         ; number of elements
  1908.         MOV     ESI, [X]                         ; pointer to X
  1909.         MOV     EDI, [Y]                         ; pointer to Y
  1910.         XOR     ECX, ECX
  1911.         LEA     ESI, [ESI+DSIZE*EAX]             ; point to end of X
  1912.         SUB     ECX, EAX                         ; -N
  1913.         LEA     EDI, [EDI+DSIZE*EAX]             ; point to end of Y
  1914.         JZ      SHORT L3                         ; test for N = 0
  1915.         FLD     DSIZE PTR [DA]
  1916.         FMUL    DSIZE PTR [ESI+DSIZE*ECX]        ; DA * X[0]
  1917.         JMP     SHORT L2                         ; jump into loop
  1918. L1:     FLD     DSIZE PTR [DA]
  1919.         FMUL    DSIZE PTR [ESI+DSIZE*ECX]        ; DA * X[i]
  1920.         FXCH                                     ; get old result
  1921.         FSTP    DSIZE PTR [EDI+DSIZE*ECX-DSIZE]  ; store Y[i]
  1922. L2:     FSUBR   DSIZE PTR [EDI+DSIZE*ECX]        ; subtract from Y[i]
  1923.         INC     ECX                              ; increment index
  1924.         JNZ     L1                               ; loop
  1925.         FSTP    DSIZE PTR [EDI+DSIZE*ECX-DSIZE]  ; store last result
  1926. L3:
  1927.  
  1928. Here we are using the same methods as in example 6: Using the loop counter 
  1929. as index register and counting through negative values up to zero. The end
  1930. of one operation overlaps with the beginning of the next.  
  1931.  
  1932. The interleaving of floating point operations work perfectly here: The 2 
  1933. clock stall between FMUL and FSUBR is filled with the FSTP of the previous 
  1934. result. The 3 clock stall between FSUBR and FSTP is filled with the loop 
  1935. overhead and the first two instructions of the next operation. An AGI stall 
  1936. has been avoided by reading the only parameter that doesn't depend on the 
  1937. index in the first clock cycle after the index has been incremented.  
  1938.  
  1939. This solution takes 6 clock cycles per operation, which is better than the 
  1940. unrolled solution published by Intel!  
  1941.  
  1942. Unrolling floating point loops
  1943. ------------------------------
  1944. The DAXPY loop unrolled by 3 is quite complicated:
  1945.  
  1946. Example 12:
  1947. DSIZE = 8                                 ; data size
  1948. IF DSIZE EQ 4
  1949. SHIFTCOUNT = 2
  1950. ELSE
  1951. SHIFTCOUNT = 3
  1952. ENDIF
  1953.  
  1954.         MOV     EAX, [N]                  ; number of elements
  1955.         MOV     ECX, 3*DSIZE              ; counter bias
  1956.         SHL     EAX, SHIFTCOUNT           ; DSIZE*N
  1957.         JZ      L4                        ; N = 0
  1958.         MOV     ESI, [X]                  ; pointer to X
  1959.         SUB     ECX, EAX                  ; (3-N)*DSIZE
  1960.         MOV     EDI, [Y]                  ; pointer to Y
  1961.         SUB     ESI, ECX                  ; end of pointer - bias
  1962.         SUB     EDI, ECX
  1963.         TEST    ECX, ECX
  1964.         FLD     DSIZE PTR [ESI+ECX]       ; first X
  1965.         JNS     SHORT L2                  ; less than 4 operations
  1966. L1:     ; main loop
  1967.         FMUL    DSIZE PTR [DA]
  1968.         FLD     DSIZE PTR [ESI+ECX+DSIZE]
  1969.         FMUL    DSIZE PTR [DA]
  1970.         FXCH
  1971.         FSUBR   DSIZE PTR [EDI+ECX]
  1972.         FXCH
  1973.         FLD     DSIZE PTR [ESI+ECX+2*DSIZE]
  1974.         FMUL    DSIZE PTR [DA]
  1975.         FXCH
  1976.         FSUBR   DSIZE PTR [EDI+ECX+DSIZE]
  1977.         FXCH    ST(2)
  1978.         FSTP    DSIZE PTR [EDI+ECX]
  1979.         FSUBR   DSIZE PTR [EDI+ECX+2*DSIZE]
  1980.         FXCH
  1981.         FSTP    DSIZE PTR [EDI+ECX+DSIZE]
  1982.         FLD     DSIZE PTR [ESI+ECX+3*DSIZE]
  1983.         FXCH
  1984.         FSTP    DSIZE PTR [EDI+ECX+2*DSIZE]
  1985.         ADD     ECX, 3*DSIZE
  1986.         JS      L1                        ; loop
  1987. L2:     FMUL    DSIZE PTR [DA]            ; finish leftover operation
  1988.         FSUBR   DSIZE PTR [EDI+ECX]
  1989.         SUB     ECX, 2*DSIZE              ; change pointer bias
  1990.         JZ      SHORT L3                  ; finished
  1991.         FLD     DSIZE PTR [DA]            ; start next operation
  1992.         FMUL    DSIZE PTR [ESI+ECX+3*DSIZE]
  1993.         FXCH
  1994.         FSTP    DSIZE PTR [EDI+ECX+2*DSIZE]
  1995.         FSUBR   DSIZE PTR [EDI+ECX+3*DSIZE]
  1996.         ADD     ECX, 1*DSIZE
  1997.         JZ      SHORT L3                  ; finished
  1998.         FLD     DSIZE PTR [DA]
  1999.         FMUL    DSIZE PTR [ESI+ECX+3*DSIZE]
  2000.         FXCH
  2001.         FSTP    DSIZE PTR [EDI+ECX+2*DSIZE]
  2002.         FSUBR   DSIZE PTR [EDI+ECX+3*DSIZE]
  2003.         ADD     ECX, 1*DSIZE
  2004. L3:     FSTP    DSIZE PTR [EDI+ECX+2*DSIZE]
  2005. L4:
  2006.  
  2007. The reason why I am showing you how to unroll a loop by 3 is not to 
  2008. recommend it, but to warn you how difficult it is! Be prepared to spend a 
  2009. considerable amount of time debugging and verifying your code when doing
  2010. something like this. There are several problems to take care of: In most 
  2011. cases, you cannot remove all stalls from a floating point loop unrolled by 
  2012. less than 4 unless you convolute it (i.e. there are unfinished operations at
  2013. the end of each run which are being finished in the next run). The last FLD 
  2014. in the main loop above is the beginning of the first operation in the next 
  2015. run. It would be tempting here to make a solution which reads past the end 
  2016. of the array and then discards the extra value in the end, as in example 9
  2017. and 10, but that is not recommended in floating point loops because the
  2018. reading of the extra value might generate a denormal operand exception in
  2019. case the memory position after the array doesn't contain a valid floating 
  2020. point number. To avoid this, we have to do at least one more operation after 
  2021. the main loop.  
  2022.  
  2023. The number of operations to do outside an unrolled loop would normally be
  2024. N MODULO R, where N is the number of operations, and R is the unrolling
  2025. factor.  But in the case of a convoluted loop, we have to do one more, i.e.
  2026. (N-1) MODULO R + 1, for the abovementioned reason.  
  2027.  
  2028. Normally, we would prefer to do the extra operations before the main loop, 
  2029. but here we have to do them afterwards for two reasons: One reason is to
  2030. take care of the leftover operand from the convolution. The other reason is
  2031. that calculating the number of extra operations requires a division if R is
  2032. not a power of 2, and a division is time consuming. Doing the extra
  2033. operations after the loop saves the division.
  2034.  
  2035. The next problem is to calculate how to bias the loop counter so that it 
  2036. will change sign at the right time, and adjust the base pointers so as to 
  2037. compensate for this bias. Finally, you have to make sure the leftover 
  2038. operand from the convolution is handled correctly for all values of N.
  2039.  
  2040. The epilog code doing 1-3 operations could have been implemented as a
  2041. separate loop, but that would cost an extra branch misprediction, so the 
  2042. solution above is faster.  
  2043.  
  2044. Now that I have scared you by demonstrating how difficult it is to unroll by 
  2045. 3, I will show you that it is much easier to unroll by 4: 
  2046.  
  2047. Example 13:
  2048.  
  2049. DSIZE   = 8                               ; data size
  2050.         MOV     EAX, [N]                  ; number of elements
  2051.         MOV     ESI, [X]                  ; pointer to X
  2052.         MOV     EDI, [Y]                  ; pointer to Y
  2053.         XOR     ECX, ECX
  2054.         LEA     ESI, [ESI+DSIZE*EAX]      ; point to end of X
  2055.         SUB     ECX, EAX                  ; -N
  2056.         LEA     EDI, [EDI+DSIZE*EAX]      ; point to end of Y
  2057.         TEST    AL,1                      ; test if N is odd
  2058.         JZ      SHORT L1
  2059.         FLD     DSIZE PTR [DA]            ; do the odd operation
  2060.         FMUL    DSIZE PTR [ESI+DSIZE*ECX]
  2061.         FSUBR   DSIZE PTR [EDI+DSIZE*ECX]
  2062.         INC     ECX                       ; adjust counter
  2063.         FSTP    DSIZE PTR [EDI+DSIZE*ECX-DSIZE]
  2064. L1:     TEST    AL,2                      ; test for possibly 2 more operations
  2065.         JZ      L2
  2066.         FLD     DSIZE PTR [DA]            ; N MOD 4 = 2 or 3. Do two more
  2067.         FMUL    DSIZE PTR [ESI+DSIZE*ECX]
  2068.         FLD     DSIZE PTR [DA]
  2069.         FMUL    DSIZE PTR [ESI+DSIZE*ECX+DSIZE]
  2070.         FXCH
  2071.         FSUBR   DSIZE PTR [EDI+DSIZE*ECX]
  2072.         FXCH
  2073.         FSUBR   DSIZE PTR [EDI+DSIZE*ECX+DSIZE]
  2074.         FXCH
  2075.         FSTP    DSIZE PTR [EDI+DSIZE*ECX]
  2076.         FSTP    DSIZE PTR [EDI+DSIZE*ECX+DSIZE]
  2077.         ADD     ECX, 2                    ; counter is now divisible by 4
  2078. L2:     TEST    ECX, ECX
  2079.         JZ      L4                        ; no more operations
  2080. L3:     ; main loop:
  2081.         FLD     DSIZE PTR [DA]
  2082.         FLD     DSIZE PTR [ESI+DSIZE*ECX]
  2083.         FMUL    ST,ST(1)
  2084.         FLD     DSIZE PTR [ESI+DSIZE*ECX+DSIZE]
  2085.         FMUL    ST,ST(2)
  2086.         FLD     DSIZE PTR [ESI+DSIZE*ECX+2*DSIZE]
  2087.         FMUL    ST,ST(3)
  2088.         FXCH    ST(2)
  2089.         FSUBR   DSIZE PTR [EDI+DSIZE*ECX]
  2090.         FXCH    ST(3)
  2091.         FMUL    DSIZE PTR [ESI+DSIZE*ECX+3*DSIZE]
  2092.         FXCH
  2093.         FSUBR   DSIZE PTR [EDI+DSIZE*ECX+DSIZE]
  2094.         FXCH    ST(2)
  2095.         FSUBR   DSIZE PTR [EDI+DSIZE*ECX+2*DSIZE]
  2096.         FXCH
  2097.         FSUBR   DSIZE PTR [EDI+DSIZE*ECX+3*DSIZE]
  2098.         FXCH    ST(3)
  2099.         FSTP    DSIZE PTR [EDI+DSIZE*ECX]
  2100.         FSTP    DSIZE PTR [EDI+DSIZE*ECX+2*DSIZE]
  2101.         FSTP    DSIZE PTR [EDI+DSIZE*ECX+DSIZE]
  2102.         FSTP    DSIZE PTR [EDI+DSIZE*ECX+3*DSIZE]
  2103.         ADD     ECX, 4                             ; increment index by 4
  2104.         JNZ     L3                                 ; loop
  2105. L4:
  2106.  
  2107. It is usually quite easy to find a stall-free solution when unrolling by 4, 
  2108. and there is no need for convolution. The number of extra operations to do
  2109. outside the main loop is N MODULO 4, which can be calculated easily without
  2110. division, simply by testing the two lowest bits in N. The extra operations
  2111. are done before the main loop rather than after, to make the handling of the 
  2112. loop counter simpler.  
  2113.  
  2114. The tradeoff of loop unrolling is that the extra operations outside the loop 
  2115. are slower due to incomplete overlapping and possible branch mispredictions, 
  2116. and the first time penalty is higher because of increased code size.  
  2117.  
  2118. As a general recommendation, I would say that if N is big or if convoluting 
  2119. the loop without unrolling cannot remove enough stalls, then you should
  2120. unroll critical integer loops by 2 and floating point loops by 4.  
  2121.  
  2122.  
  2123. 17. DISCUSSION OF SPECIAL INSTRUCTIONS
  2124. ======================================
  2125.  
  2126. 17.1 LEA
  2127. --------
  2128. The LEA instruction is useful for many purposes because it can do a shift,
  2129. two additions, and a move in just one pairable instruction taking one clock
  2130. cycle.  Example:
  2131. LEA EAX,[EBX+8*ECX-1000]
  2132. is much faster than
  2133. MOV EAX,ECX / SHL EAX,3 / ADD EAX,EBX / SUB EAX,1000
  2134. The LEA instruction can also be used to do an add or shift without changing
  2135. the flags. The source and destination need not have the same word size, so
  2136. LEA EAX,[BX]  is a useful replacement for  MOVZX EAX,BX.
  2137.  
  2138. You must be aware, however, that the LEA instruction will suffer an AGI
  2139. stall if it uses a base or index register which has been changed in the
  2140. preceding clock cycle.
  2141.  
  2142. Since the LEA instruction is pairable in the V-pipe and shift instructions
  2143. are not, you may use LEA as a substitute for a SHL by 1, 2, or 3 if you want
  2144. the instruction to execute in the V-pipe.
  2145.  
  2146. The 32 bit processors have no documented addressing mode with a scaled index
  2147. register and nothing else, so an instruction like  LEA EAX,[EAX*2]  is
  2148. actually coded as  LEA EAX,[EAX*2+00000000]  with an immediate displacement
  2149. of 4 bytes.  You may reduce the instruction size by instead writing  LEA
  2150. EAX,[EAX+EAX] or even better  ADD EAX,EAX.  The latter code cannot have an
  2151. AGI delay. If you happen to have a register which is zero (like a loop 
  2152. counter after a loop), then you may use it as a base register to reduce the
  2153. code size: 
  2154.  
  2155. LEA EAX,[EBX*4]     ; 7 bytes
  2156. LEA EAX,[ECX+EBX*4] ; 3 bytes
  2157.  
  2158.  
  2159. 17.2 MOV [MEM],ACCUM
  2160. --------------------
  2161. The instructions  MOV [mem],AL   MOV [mem],AX   MOV [mem],EAX
  2162. are treated by the pairing circuitry as if they were writing to the
  2163. accumulator. Thus the following instructions do not pair:
  2164. MOV [mydata], EAX
  2165. MOV EBX, EAX
  2166.  
  2167. This problem occurs only with the short form of the MOV instruction which
  2168. can not have a base or index register, and which can only have the
  2169. accumulator as source. You can avoid the problem by using another register,
  2170. by reordering your instructions, by using a pointer, or by hard-coding the
  2171. general form of the MOV instruction.
  2172.  
  2173. In 32 bit mode you can write the general form of MOV [mem],EAX:
  2174. DB 89H, 05H
  2175. DD OFFSET DS:[mem]
  2176.  
  2177. In 16 bit mode you can write the general form of MOV [mem],AX:
  2178. DB 89H, 06H
  2179. DW OFFSET DS:[mem]
  2180.  
  2181. To use AL instead of (e)AX, you replace 89H with 88H
  2182.  
  2183.  
  2184. 17.3 TEST
  2185. ---------
  2186. The TEST instruction with an immediate operand is only pairable if the
  2187. destination is AL, AX, or EAX.
  2188.  
  2189. TEST register,register  and  TEST register,memory  is always pairable.
  2190.  
  2191. Examples:
  2192. TEST ECX,ECX                ; pairable
  2193. TEST [mem],EBX              ; pairable
  2194. TEST EDX,256                ; not pairable
  2195. TEST DWORD PTR [EBX],8000H  ; not pairable
  2196. To make it pairable, use any of the following methods:
  2197. MOV EAX,[EBX] / TEST EAX,8000H
  2198. MOV EDX,[EBX] / AND  EDX,8000H
  2199. MOV AL,[EBX+1] / TEST AL,80H
  2200. MOV AL,[EBX+1] / TEST AL,AL  ; (result in sign flag)
  2201. It is also possible to test a bit by shifting it into the carry flag:
  2202. MOV EAX,[EBX] / SHR EAX,16   ; (result in carry flag)
  2203. but this method has a penalty on the PentiumPro when the shift count is more
  2204. than one.
  2205.  
  2206. (The reason for this non-pairability is probably that the first byte of the
  2207. 2-byte instruction is the same as for some other non-pairable instructions,
  2208. and the Pentium cannot afford to check the second byte too when determining
  2209. pairability.)
  2210.  
  2211.  
  2212. 17.4 XCHG
  2213. ---------
  2214. The  XCHG register,memory  instruction is dangerous. By default this
  2215. instruction has an implicit LOCK prefix which prevents it from using the
  2216. cache. The instruction is therefore very time consuming, and should always
  2217. be avoided.
  2218.  
  2219.  
  2220. 17.5 rotates through carry
  2221. --------------------------
  2222. RCR and RCL with a count different from one are slow and should be avoided.
  2223.  
  2224.  
  2225. 17.6 string instructions
  2226. ------------------------
  2227. String instructions without a repeat prefix are too slow, and should always
  2228. be replaced by simpler instructions. The same applies to LOOP and JECXZ.  
  2229.  
  2230. String instructions with repeat may be optimal. Always use the dword version
  2231. if possible, and make sure that both source and destination are aligned by 4.
  2232.  
  2233. REP MOVSD is the fastest way to move blocks of data when the destination is
  2234. in the level 1 cache. See section 19 for an alternative.
  2235. Note that while the REP MOVSD instruction writes a DWORD to the destination,
  2236. it reads the next DWORD from the source in the same clock cycle. According
  2237. to rule 10.3 above, you have a cache bank conflict if bit 2-4 are the same
  2238. in these two addresses. In other words, you will get a penalty of one clock
  2239. extra per iteration if ESI+4-EDI is divisible by 32. This can be avoided if
  2240. both source and destination are aligned by 8.
  2241.  
  2242. REP STOSD is optimal when the destination is in the cache.
  2243.  
  2244. REP LOADS, REP SCAS, and REP CMPS are not optimal, and may be replaced by
  2245. loops. See section 16 example 10 for an alternative to REP SCASB.
  2246.  
  2247.  
  2248. 17.7 bit scan
  2249. -------------
  2250. BSF and BSR are the poorest optimized instructions on the Pentium, taking
  2251. approximately 11 + 2*n clock cycles, where n is the number of zeros skipped.
  2252. (on later processors it takes only 1 or 2)
  2253.  
  2254. The following code emulates BSR ECX,EAX:
  2255.         TEST    EAX,EAX
  2256.         JZ      SHORT BS1
  2257.         MOV     DWORD PTR [TEMP],EAX
  2258.         MOV     DWORD PTR [TEMP+4],0
  2259.         FILD    QWORD PTR [TEMP]
  2260.         FSTP    QWORD PTR [TEMP]
  2261.         WAIT    ; WAIT only needed for compatibility with earlier processors
  2262.         MOV     ECX, DWORD PTR [TEMP+4]
  2263.         SHR     ECX,20
  2264.         SUB     ECX,3FFH
  2265.         TEST    EAX,EAX       ; clear zero flag
  2266. BS1:
  2267.  
  2268. The following code emulates BSF ECX,EAX:
  2269.         TEST    EAX,EAX
  2270.         JZ      SHORT BS2
  2271.         XOR     ECX,ECX
  2272.         MOV     DWORD PTR [TEMP+4],ECX
  2273.         SUB     ECX,EAX
  2274.         AND     EAX,ECX
  2275.         MOV     DWORD PTR [TEMP],EAX
  2276.         FILD    QWORD PTR [TEMP]
  2277.         FSTP    QWORD PTR [TEMP]
  2278.         WAIT    ; WAIT only needed for compatibility with earlier processors
  2279.         MOV     ECX, DWORD PTR [TEMP+4]
  2280.         SHR     ECX,20
  2281.         SUB     ECX,3FFH
  2282.         TEST    EAX,EAX       ; clear zero flag
  2283. BS2:
  2284.  
  2285.  
  2286. 17.8 bit test
  2287. -------------
  2288. BT, BTC, BTR, and BTS instructions should preferably be replaced by
  2289. instructions like TEST, AND, OR, XOR, or shifts.
  2290.  
  2291.  
  2292. 17.9 integer multiplication
  2293. ---------------------------
  2294. An integer multiplication takes approximately 9 clock cycles. It is
  2295. therefore advantageous to replace a multiplication by a constant with a
  2296. combination of other instructions such as SHL, ADD, SUB, and LEA.  Example: 
  2297. IMUL EAX,10
  2298. can be replaced with
  2299. MOV EBX,EAX / ADD EAX,EAX / SHL EBX,3 / ADD EAX,EBX
  2300. or
  2301. LEA EAX,[EAX+4*EAX] / ADD EAX,EAX
  2302.  
  2303. Floating point multiplication is faster than integer multiplication on a 
  2304. Pentium without MMX, but the time used to convert integers to float and 
  2305. convert the product back again is usually more than the time saved by using
  2306. floating point multiplication, except when the number of conversions is low 
  2307. compared with the number of multiplications.
  2308.  
  2309.  
  2310. 17.10 division
  2311. --------------
  2312. Division is quite time consuming. The DIV instruction takes 17, 25, or 41
  2313. clock cycles for byte, word, and dword divisors respectively. The IDIV
  2314. instruction takes 5 clock cycles more. It is therefore preferable to use the
  2315. smallest operand size possible that won't generate an overflow, even if it
  2316. costs an operand size prefix, and use unsigned division if possible.
  2317.  
  2318. Unsigned division by a power of two can be done with SHR.  Division of a
  2319. signed number by a power of two can be done with SAR, but the result with
  2320. SAR is rounded towards minus infinity, whereas the result with IDIV is
  2321. truncated towards zero.
  2322.  
  2323. Dividing a positive number N (< 2^16) with a constant D which is not a
  2324. power of two can be done by multiplying N with 2^16 / D and then dividing
  2325. with 2^16. For example, to divide a number with 5, you may multiply with
  2326. 2^16 / 5 = 3333H, and then divide with 2^16:
  2327.  
  2328. INC EAX  /  IMUL EAX,3333H  /  SHR EAX,16
  2329.  
  2330. The  INC EAX  is added to compensate for the double rounding error.
  2331. This method works for 0 <= N <= 2^16. You have to test the code thoroughly
  2332. to make sure the rounding is correct.
  2333.  
  2334. If you want to replace the IMUL with faster pairable instructions, then
  2335. you may write:
  2336.  
  2337.         LEA     EBX,[EAX+2*EAX+3]
  2338.         LEA     ECX,[EAX+2*EAX+3]
  2339.         SHL     EBX,4
  2340.         MOV     EAX,ECX
  2341.         SHL     ECX,8
  2342.         ADD     EAX,EBX
  2343.         SHL     EBX,8
  2344.         ADD     EAX,ECX
  2345.         ADD     EAX,EBX
  2346.         SHR     EAX,16
  2347.  
  2348. You can use the same code to divide by 10. Just shift right by 17
  2349. instead of 16 in the end.
  2350.  
  2351.  
  2352. Floating point division takes 39 clock cycles for the highest precision.
  2353. You can save time by specifying a lower precision in the floating point
  2354. control word (only FDIV and FIDIV are faster at low precision, no other
  2355. instructions can be speeded up this way).
  2356.  
  2357. It is possible to do a floating point division and an integer division in
  2358. parallel to save time.  Example: A = A1 / A2;  B = B1 / B2
  2359.  
  2360. FILD [B1]
  2361. FILD [B2]
  2362. MOV EAX,[A1]
  2363. MOV EBX,[A2]
  2364. CDQ
  2365. FDIV
  2366. DIV EBX
  2367. FISTP [B]
  2368. MOV [A],EAX
  2369. (make sure you set the floating point control word to the desired
  2370. rounding method)
  2371.  
  2372. Obviously, you should always try to minimize the number of divisions.
  2373. Floating point division with a constant or repeated division with the same
  2374. value should of course by done by multiplying with the reciprocal.
  2375. But there are many other situations where you can reduce the number of
  2376. divisions. For example:
  2377. if (A/B > C)...  can be rewritten as  if (A > B*C)...  when B is
  2378. positive, and the opposite when B is negative.
  2379.  
  2380. A/B + C/D  can be rewritten as  (A*D + C*B) / (B*D)
  2381.  
  2382. If you are using integer division, then you should be aware that the
  2383. rounding errors may be different when you rewrite the formulas.
  2384.  
  2385.  
  2386. 17.11 WAIT
  2387. ----------
  2388. You can often increase speed by omitting the WAIT instruction.
  2389. The WAIT instruction has three functions:
  2390.  
  2391.   a. The 8087 processor requires a WAIT before _every_ floating point
  2392.      instruction to make sure the coprocessor is ready to receive it.
  2393.  
  2394.   b. WAIT is used to coordinate memory access between the floating point
  2395.      unit and the integer unit. Examples:
  2396.      b.1.  FISTP [mem32]
  2397.            WAIT             ; wait for floating point unit to write before..
  2398.            MOV EAX,[mem32]  ; reading the result with the integer unit
  2399.  
  2400.      b.2.  FILD [mem32]
  2401.            WAIT             ; wait for floating point unit to read value..
  2402.            MOV [mem32],EAX  ; before overwriting it with integer unit
  2403.  
  2404.      b.3.  FLD QWORD PTR [ESP]
  2405.            WAIT             ; prevent an accidental hardware interrupt from..
  2406.            ADD ESP,8        ; overwriting value on stack before it is read
  2407.  
  2408.   c. WAIT is sometimes used to check for exceptions. It will generate an
  2409.      interrupt if an unmasked exception bit in the floating point status
  2410.      word has been set by a preceding floating point instruction.
  2411.  
  2412. Regarding a:
  2413. The function in point a is never needed on any other processors than the old
  2414. 8087. Unless you want your code to be compatible with the 8087 you should
  2415. tell your assembler not to put in these WAITs by specifying a higher
  2416. processor. A 8087 floating point emulator also inserts WAIT instructions.
  2417. You should therefore tell your assembler not to generate emulation code
  2418. unless you need it.
  2419.  
  2420. Regarding b:
  2421. WAIT instructions to coordinate memory access are definitely needed on the
  2422. 8087 and 80287 but not on the Pentium. It is not quite clear whether it is
  2423. needed on the 80387 and 80486. I have made several tests on these Intel
  2424. processors and not been able to provoke any error by omitting the WAIT on
  2425. any 32 bit Intel processor, although Intel manuals say that the WAIT is
  2426. needed for this purpose except after FNSTSW and FNSTCW. Omitting WAIT
  2427. instructions for coordinating memory access is not 100 % safe, even when
  2428. writing 32 bit code, because the code may be able to run on a 80386 main
  2429. processor with a 287 coprocessor, which requires the WAIT. Also, I have not
  2430. tested all possible hardware and software combinations, so there may be
  2431. other situations where the WAIT is needed.
  2432.  
  2433. If you want to be certain that your code will work on _any_ 32 bit processor
  2434. (including non-Intel processors) then I would recommend that you include the
  2435. WAIT here in order to be safe.
  2436.  
  2437. Regarding c:
  2438. The assembler automatically inserts a WAIT for this purpose before the
  2439. following instructions:  FCLEX, FINIT, FSAVE, FSTCW, FSTENV, FSTSW.
  2440. You can omit the WAIT by writing FNCLEX, etc. My tests show that the WAIT
  2441. is unneccessary in most cases because these instructions without WAIT will
  2442. still generate an interrupt on exceptions except for FNCLEX and FNINIT on
  2443. the 80387. (There is some inconsistency about whether the IRET from the
  2444. interrupt points to the FN.. instruction or to the next instruction).
  2445.  
  2446. Almost all other floating point instructions will also generate an interrupt
  2447. if a previous floating point instruction has set an unmasked exception bit,
  2448. so the exception is likely to be detected sooner or later anyway. You may
  2449. insert a WAIT after the last floating point instruction in your program to
  2450. be sure to catch all exceptions.
  2451.  
  2452. You may still need the WAIT if you want to know exactly where an exception
  2453. occurred in order to be able to recover from the situation. Consider, for
  2454. example, the code under b.3 above: If you want to be able to recover from
  2455. an exception generated by the FLD here, then you need the WAIT because an
  2456. interrupt after ADD ESP,8 would overwrite the value to load.
  2457.  
  2458.  
  2459. 17.12 FCOM + FSTSW AX
  2460. ---------------------
  2461. The usual way of doing floating point comparisons is:
  2462. FLD [a]
  2463. FCOMP [b]
  2464. FSTSW AX
  2465. SAHF
  2466. JB ASmallerThanB
  2467.  
  2468. You may improve this code by using FNSTSW AX rather than FSTSW AX and
  2469. test AH directly rather than using the non-pairable SAHF.
  2470. (TASM version 3.0 has a bug with the FNSTSW AX instruction)
  2471.  
  2472. FLD [a]
  2473. FCOMP [b]
  2474. FNSTSW AX
  2475. SHR AH,1
  2476. JC ASmallerThanB
  2477.  
  2478. Testing for zero or equality:
  2479.  
  2480. FTST
  2481. FNSTSW AX
  2482. AND AH,40H
  2483. JNZ IsZero     ; (the zero flag is inverted!)
  2484.  
  2485. Test if greater:
  2486.  
  2487. FLD [a]
  2488. FCOMP [b]
  2489. FNSTSW AX
  2490. AND AH,41H
  2491. JZ AGreaterThanB
  2492.  
  2493. Do not use TEST AH,41H as it is not pairable. Do not use TEST EAX,4100H as
  2494. it would produce a partial register stall on the PentiumPro. Do not test the
  2495. flags after multibit shifts, as this has a penalty on the PentiumPro.
  2496.  
  2497. The FNSTSW instruction delays for 4 clocks after any floating point
  2498. instruction (probably because it is waiting for the status word to retire
  2499. from the pipeline). If you can fill this latency with integer instructions
  2500. between  FCOM  and  FNSTSW,  then the FNSTSW instruction will take only 2
  2501. clocks, rather than 6. Make sure you use the version without WAIT prefix in
  2502. this case.
  2503.  
  2504. It is some times faster to use integer instructions for comparing floating
  2505. point values, as described in paragraph 18 below.
  2506.  
  2507.  
  2508. 17.13 freeing floating point registers
  2509. --------------------------------------
  2510. You have to free all used floating point registers before exiting a
  2511. subroutine, except for any register used for the result.
  2512.  
  2513. The fastest way to free one register is  FSTP ST.
  2514. The fastest way to free two registers is  FCOMPP.
  2515. It is not recommended to use  FFREE.
  2516.  
  2517.  
  2518. 17.14 FISTP
  2519. -----------
  2520. Converting a floating point number to integer is normally done like this:
  2521.         FISTP   DWORD PTR [TEMP]
  2522.         MOV     EAX, [TEMP]
  2523.  
  2524. An alternative method is:
  2525.  
  2526. .DATA
  2527. ALIGN 8
  2528. TEMP    DQ      ?
  2529. MAGIC   DD      59C00000H   ; f.p. representation of 2^51 + 2^52
  2530.  
  2531. .CODE
  2532.         FADD    [MAGIC]
  2533.         FSTP    QWORD PTR [TEMP]
  2534.         MOV     EAX, DWORD PTR [TEMP]
  2535.  
  2536. Adding the 'magic number' of 2^51 + 2^52 has the effect that any integer
  2537. between -2^31 and +2^31 will be aligned in the lower 32 bits when storing
  2538. as a double precision floating point number. The result is the same as you
  2539. get with FISTP for all rounding methods except truncation towards zero.
  2540. The result is different from FISTP if the control word specifies truncation
  2541. or in case of overflow. You may need a WAIT instruction for compatibility
  2542. with other processors. See section 17.11.
  2543.  
  2544. This method is not faster than using FISTP, but it gives better scheduling
  2545. opportunities because there is a 3 clock void between FADD and FSTP which
  2546. may be filled with other instrucions. You may multiply or divide the number
  2547. by a power of 2 in the same operation by doing the opposite to the magic
  2548. number. You may also add a constant by adding it to the magic number,
  2549. which then has to be double precision.
  2550.  
  2551.  
  2552. 17.15 FPTAN
  2553. -----------
  2554. According to the manuals, FPTAN returns two values X and Y and leaves it to
  2555. the programmer to divide Y with X to get the result, but in fact it always
  2556. returns 1 in X so you can save the division. My tests show that on all 32
  2557. bit Intel processors with floating point unit or coprocessor, FPTAN always
  2558. returns 1 in X regardless of the argument. If you want to be absolutely sure
  2559. that your code will run correctly on all processors, then you may test if X
  2560. is 1, which is faster than dividing with X. The Y value may be very high,
  2561. but never infinity, so you don't have to test if Y contains a valid number
  2562. if you know that the argument is valid.
  2563.  
  2564.  
  2565.  
  2566. 18. USING INTEGER INSTRUCTIONS TO DO FLOATING POINT OPERATIONS
  2567. ==============================================================
  2568. Integer instructions are generally faster than floating point instructions,
  2569. so it is often advantageous to use integer instructions for doing simple
  2570. floating point operations. The most obvious example is moving data. Example: 
  2571.  
  2572. FLD QWORD PTR [ESI] / FSTP QWORD PTR [EDI]
  2573.  
  2574. Change to:
  2575.  
  2576. MOV EAX,[ESI] / MOV EBX,[ESI+4] / MOV [EDI],EAX / MOV [EDI+4],EBX
  2577.  
  2578. The former code takes 4 clocks, the latter takes 2.
  2579.  
  2580. Testing if a floating point value is zero:
  2581.  
  2582. The floating point value of zero is usually represented as 32 or 64 bits of 
  2583. zero, but there is a pitfall here: The sign bit may be set! Minus zero is 
  2584. regarded as a valid floating point number, and the processor may actually 
  2585. generate a zero with the sign bit set if for example multiplying a negative
  2586. number with zero. So if you want to test if a floating point number is zero,
  2587. you should not test the sign bit. Example:
  2588.  
  2589. FLD DWORD PTR [EBX] / FTST / FNSTSW AX / AND AH,40H / JNZ IsZero
  2590.  
  2591. Use integer instructions instead, and shift out the sign bit:
  2592.  
  2593. MOV EAX,[EBX] / ADD EAX,EAX / JZ IsZero
  2594.  
  2595. The former code takes 9 clocks, the latter takes only 2.
  2596. If the floating point number is double precision (QWORD) then you only have
  2597. to test bit 32-62. If they are zero, then the lower half will also be zero
  2598. if it is a normal floating point number.
  2599.  
  2600. Testing if negative:
  2601. A floating point number is negative if the sign bit is set and at least one
  2602. other bit is set. Example:
  2603. MOV EAX,[NumberToTest] / CMP EAX,80000000H / JA IsNegative
  2604.  
  2605. Manipulating the sign bit:
  2606. You can change the sign of a floating point number simply by flipping the
  2607. sign bit. Example:
  2608. XOR BYTE PTR [a] + (TYPE a) - 1, 80H
  2609.  
  2610. Likewise you may get the absolute value of a floating point number by simply
  2611. ANDing out the sign bit.
  2612.  
  2613. Comparing numbers:
  2614. Floating point numbers are stored in a unique format which allows you to use
  2615. integer instructions for comparing floating point numbers, except for the
  2616. sign bit. If you are certain that two floating point numbers both are normal
  2617. and positive then you may simply compare them as integers. Example:
  2618.  
  2619. FLD [a] / FCOMP [b] / FNSTSW AX / AND AH,1 / JNZ ASmallerThanB
  2620.  
  2621. Change to:
  2622.  
  2623. MOV EAX,[a] / MOV EBX,[b] / CMP EAX,EBX / JB ASmallerThanB
  2624.  
  2625. This method only works if the two numbers have the same precision and you
  2626. are certain that none of the numbers have the sign bit set.
  2627.  
  2628. If negative numbers are possible, then you have to convert the
  2629. negative numbers to 2-complement, and do a signed compare:
  2630.  
  2631. MOV EAX,[a]
  2632. MOV EBX,[b]
  2633. MOV ECX,EAX
  2634. MOV EDX,EBX
  2635. SAR ECX,31              ; copy sign bit
  2636. AND EAX,7FFFFFFFH       ; remove sign bit
  2637. SAR EDX,31
  2638. AND EBX,7FFFFFFFH
  2639. XOR EAX,ECX             ; make 2-complement if sign bit was set
  2640. XOR EBX,EDX
  2641. SUB EAX,ECX
  2642. SUB EBX,EDX
  2643. CMP EAX,EBX
  2644. JL  ASmallerThanB       ; signed comparison
  2645.  
  2646. This method works for all normal floating point numbers, including -0.
  2647.  
  2648.  
  2649. 19. USING FLOATING POINT INSTRUCTIONS TO DO INTEGER OPERATIONS
  2650. ==============================================================
  2651. 19.1 Moving data
  2652. ----------------
  2653. Floating point instructions can be used to move 8 bytes at a time:
  2654. FILD QWORD PTR [ESI] / FISTP QWORD PTR [EDI]
  2655. This is only an advantage if the destination is not in the cache. The
  2656. optimal way to move a block of data to uncached memory on the Pentium is:
  2657.  
  2658. TopOfLoop:
  2659. FILD QWORD PTR [ESI]
  2660. FILD QWORD PTR [ESI+8]
  2661. FXCH
  2662. FISTP QWORD PTR [EDI]
  2663. FISTP QWORD PTR [EDI+8]
  2664. ADD ESI,16
  2665. ADD EDI,16
  2666. DEC ECX
  2667. JNZ TopOfLoop
  2668.  
  2669. The source and destination should of course be aligned by 8. The extra time
  2670. used by the slow FILD and FISTP instructions is compensated for by the fact
  2671. that you only have to do half as many write operations.  Note that this 
  2672. method is only advantageous on the Pentium and only if the destination is
  2673. not in the level 1 cache. On all other processors the optimal way to move
  2674. blocks of data is REP MOVSD, or if you have a processor with MMX you may use
  2675. the MMX instructions instead to write 8 bytes at a time.
  2676.  
  2677. 19.2 Integer multiplication
  2678. ---------------------------
  2679. Floating point multiplication is faster than integer multiplication on the 
  2680. Pentium without MMX, but the price for converting integer factors to float
  2681. and converting the result back to integer is high, so floating point
  2682. multiplication is only advantageous if the number of conversions needed is 
  2683. low compared with the number of multiplications. Integer multiplication is
  2684. faster than floating point on other processors.
  2685.  
  2686. It may be tempting to use denormal floating point operands to save some of
  2687. the conversions here, but the handling of denormals is very slow, so this
  2688. is not a good idea!
  2689.  
  2690. 19.3 Integer division
  2691. ---------------------
  2692. Floating point division is not faster than integer division, but you can do 
  2693. other integer operations (including integer division, but not integer 
  2694. multiplication) while the floating point unit is working on the division. 
  2695. See paragraph 17.10 above for an example.
  2696.  
  2697. 19.4 Converting binary to decimal numbers
  2698. -----------------------------------------
  2699. Using the FBSTP instruction is a simple and convenient way of converting a 
  2700. binary number to decimal, although not necessarily the fastest method.
  2701.  
  2702.  
  2703. 20. LIST OF INTEGER INSTRUCTIONS
  2704. ================================
  2705. Explanations:
  2706. Operands: r=register, m=memory, i=immediate data, sr=segment register
  2707. m32= 32 bit memory operand, etc.
  2708.  
  2709. Clock cycles:
  2710. The numbers are minimum values. Cache misses, misalignment, and exceptions
  2711. may increase the clock counts considerably.
  2712.  
  2713. Pairability:
  2714. u=pairable in U-pipe, v=pairable in V-pipe, uv=pairable in either pipe,
  2715. np=not pairable
  2716.  
  2717. Opcode                 Operands            Clock cycles        Pairability
  2718. ----------------------------------------------------------------------------
  2719. NOP                                        1                   uv
  2720. MOV                    r/m, r/m/i          1                   uv
  2721. MOV                    r/m, sr             1                   np
  2722. MOV                    sr , r/m            >= 2 b)             np
  2723. MOV                    m  , accum          1                   uv h)
  2724. XCHG                   (E)AX, r            2                   np
  2725. XCHG                   r  ,   r            3                   np
  2726. XCHG                   r  ,   m            >20                 np
  2727. XLAT                                       4                   np
  2728. PUSH                   r/i                 1                   uv
  2729. POP                    r                   1                   uv
  2730. PUSH                   m                   2                   np
  2731. POP                    m                   3                   np
  2732. PUSH                   sr                  1 b)                np
  2733. POP                    sr                  >= 3 b)             np
  2734. PUSHF                                      4                   np
  2735. POPF                                       6                   np
  2736. PUSHA POPA                                 5                   np
  2737. LAHF SAHF                                  2                   np
  2738. MOVSX MOVZX            r, r/m              3 a)                np
  2739. LEA                    r/m                 1                   uv
  2740. LDS LES LFS LGS LSS    m                   4 c)                np
  2741. ADD SUB AND OR XOR     r  , r/i            1                   uv
  2742. ADD SUB AND OR XOR     r  , m              2                   uv
  2743. ADD SUB AND OR XOR     m  , r/i            3                   uv
  2744. ADC SBB                r  , r/i            1                   u
  2745. ADC SBB                r  , m              2                   u
  2746. ADC SBB                m  , r/i            3                   u
  2747. CMP                    r  , r/i            1                   uv
  2748. CMP                    m  , r/i            2                   uv
  2749. TEST                   r  , r              1                   uv
  2750. TEST                   m  , r              2                   uv
  2751. TEST                   r  , i              1                   f)
  2752. TEST                   m  , i              2                   np
  2753. INC DEC                r                   1                   uv
  2754. INC DEC                m                   3                   uv
  2755. NEG NOT                r/m                 1/3                 np
  2756. MUL IMUL               r8/r16/m8/m16      11                   np
  2757. MUL IMUL               all other versions  9 d)                np
  2758. DIV                    r8/r16/r32          17/25/41            np
  2759. IDIV                   r8/r16/r32          22/30/46            np
  2760. CBW CWDE                                   3                   np
  2761. CWD CDQ                                    2                   np
  2762. SHR SHL SAR SAL        r  , i              1                   u
  2763. SHR SHL SAR SAL        m  , i              3                   u
  2764. SHR SHL SAR SAL        r/m, CL             4/5                 np
  2765. ROR ROL RCR RCL        r/m, 1              1/3                 u
  2766. ROR ROL                r/m, i(><1)         1/3                 np
  2767. ROR ROL                r/m, CL             4/5                 np
  2768. RCR RCL                r/m, i(><1)         8/10                np
  2769. RCR RCL                r/m, CL             7/9                 np
  2770. SHLD SHRD              r, i/CL             4 a)                np
  2771. SHLD SHRD              m, i/CL             5 a)                np
  2772. BT                     r, r/i              4 a)                np
  2773. BT                     m, i                4 a)                np
  2774. BT                     m, r                9 a)                np
  2775. BTR BTS BTC            r, r/i              7 a)                np
  2776. BTR BTS BTC            m, i                8 a)                np
  2777. BTR BTS BTC            m, r               14 a)                np
  2778. BSF BSR                r  , r/m            7-73 a)             np
  2779. SETcc                  r/m                 1/2 a)              np
  2780. JMP CALL               short/near          1/4 e)              v
  2781. JMP CALL               far                 >= 3 e)             np
  2782. conditional jump       short/near          1/4/5 e)            v
  2783. CALL JMP               r/m                 2/5 e)              np
  2784. RETN                                       2/5 e)              np
  2785. RETN                   i                   3/6 e)              np
  2786. RETF                                       4/7 e)              np
  2787. RETF                   i                   5/8 e)              np
  2788. J(E)CXZ                short               5-8 e)              np
  2789. LOOP                   short               5-9 e)              np
  2790. BOUND                  r  , m              8                   np
  2791. CLC STC CMC CLD STD                        2                   np
  2792. CLI STI                                    6-7                 np
  2793. LODS                                       2                   np
  2794. REP LODS                                   7+3*n g)            np
  2795. STOS                                       3                   np
  2796. REP STOS                                   10+n  g)            np
  2797. MOVS                                       4                   np
  2798. REP MOVSB                                  12+1.8*n g)         np
  2799. REP MOVSW                                  12+1.5*n g)         np
  2800. REP MOVSD                                  12+n     g)         np
  2801. SCAS                                       4                   np
  2802. REP(N)E SCAS                               9+4*n    g)         np
  2803. CMPS                                       5                   np
  2804. REP(N)E CMPS                               8+5*n    g)         np
  2805. BSWAP                                      1 a)                np
  2806. CPUID                                      13/15/16 a)         np
  2807. RDTSC                                      6 a)                np
  2808. ----------------------------------------------------------------------------
  2809. Notes:
  2810. a) this instruction has a 0FH prefix which takes one clock cycle extra to
  2811.    decode on a Pentium without MMX unless preceded by a multicycle
  2812.    instruction (see section 13 above).
  2813. b) versions with FS and GS have a 0FH prefix. see note a.
  2814. c) versions with SS, FS, and GS have a 0FH prefix. see note a.
  2815. d) versions with two operands and no immediate have a 0FH prefix, see note a.
  2816. e) see section 12 above
  2817. f) only pairable if register is accumulator. see paragraph 17.3 above
  2818. g) add one clock cycle for decoding the repeat prefix unless preceded by a
  2819.    multicycle instruction (such as CLD. see section 13 above).
  2820. h) pairs as if it were writing to the accumulator. see paragraph 17.2 above.
  2821.  
  2822.  
  2823. 21. LIST OF FLOATING POINT INSTRUCTIONS
  2824. =======================================
  2825. Explanations:
  2826. Operands: r=register, m=memory, m32=32 bit memory operand, etc.
  2827.  
  2828. Clock cycles:
  2829. The numbers are minimum values. Cache misses, misalignment, denormal
  2830. operands, and exceptions may increase the clock counts considerably.
  2831.  
  2832. Pairability:
  2833. +=pairable with FXCH, np=not pairable with FXCH.
  2834.  
  2835. i-ov:
  2836. Overlap with integer instructions. i-ov = 4 means that the last four clock
  2837. cycles can overlap with subsequent integer instructions.  
  2838.  
  2839. fp-ov:
  2840. Overlap with floating point instructions. fp-ov = 2 means that the last two 
  2841. clock cycles can overlap with subsequent floating point instructions.
  2842. (WAIT is considered a floating point instruction here)
  2843.  
  2844. Opcode               Operand     Clock cycles    Pairability    i-ov   fp-ov
  2845. -----------------------------------------------------------------------------
  2846. FLD                  r/m32/m64         1         +              0      0
  2847. FLD                  m80               3         np             0      0
  2848. FBLD                 m80           48-58         np             0      0
  2849. FST(P)               r                 1         np             0      0
  2850. FST(P)               m32/m64           2 i)      np             0      0
  2851. FST(P)               m80               3 i)      np             0      0
  2852. FBSTP                m80         148-154         np             0      0
  2853. FILD                 m                 3         np             2      2
  2854. FIST(P)              m                 6         np             0      0
  2855. FLDZ FLD1                              2         np             0      0
  2856. FLDPI FLDL2E etc.                      5         np             0      0
  2857. FNSTSW               AX/m16            6 n)      np             0      0
  2858. FLDCW                m16               8         np             0      0
  2859. FNSTCW               m16               2         np             0      0
  2860.  
  2861. FADD(P)              r/m               3         +              2      2
  2862. FSUB(R)(P)           r/m               3         +              2      2
  2863. FMUL(P)              r/m               3         +              2      2 j)
  2864. FDIV(R)(P)           r/m        19/33/39 m)      + k)          38 l)   2
  2865. FCHS FABS                              1         +              0      0
  2866. FCOM(P)(P) FUCOM     r/m               1         +              0      0
  2867. FIADD FISUB(R)       m                 6         np             2      2
  2868. FIMUL                m                 6         np             2      2
  2869. FIDIV(R)             m          22/36/42 m)      np            38 l)   2
  2870. FICOM                m                 4         np             0      0
  2871. FTST                                   1         np             0      0
  2872. FXAM                               17-21         np             4      0
  2873. FPREM                              16-64         np             2      2
  2874. FPREM1                             20-70         np             2      2
  2875. FRNDINT                             9-20         np             0      0
  2876. FSCALE                             20-32         np             5      0
  2877. FXTRACT                            12-66         np             0      0
  2878.  
  2879. FSQRT                                 70         np            69 l)   2
  2880. FSIN FCOS                         16-126         np             2      2
  2881. FSINCOS                           17-137         np             2      2
  2882. F2XM1                              13-57         np             2      2
  2883. FYL2X                             22-111         np             2      2
  2884. FYL2XP1                           22-103         np             2      2
  2885. FPATAN                            19-134         np             2      2
  2886. FPTAN                             17-173         np            36 l)   0
  2887.  
  2888. FNOP                                   2         np             0      0
  2889. FXCH                 r                 1         np             0      0
  2890. FINCSTP FDECSTP                        2         np             0      0
  2891. FFREE                r                 2         np             0      0
  2892. FNCLEX                               6-9         np             0      0
  2893. FNINIT                             12-22         np             0      0
  2894. FNSAVE               m           124-300         np             0      0
  2895. FRSTOR               m             70-95         np             0      0
  2896. WAIT                                   1         np             0      0
  2897. -----------------------------------------------------------------------------
  2898. Notes:
  2899. i) The value to store is needed one clock cycle in advance.
  2900. j) 1 if the overlapping instruction is also an FMUL.
  2901. k) If the FXCH is followed by an integer instruction then it will pair
  2902.    imperfectly and take an extra clock cycle so that the integer
  2903.    instruction will begin in clock cycle 3.
  2904. l) Cannot overlap integer multiplication instructions.
  2905. m) FDIV takes 19, 33, or 39 clock cycles for 24, 53, and 64 bit precision
  2906.    respectively. FIDIV takes 3 clocks more. The precision is defined by bit
  2907.    8-9 of the floating point control word.
  2908. n) The first 4 clock cycles can overlap with preceding integer instructions.
  2909.    See section 17.12 above.
  2910.  
  2911.  
  2912. 22. TESTING SPEED
  2913. =================
  2914. The Pentium has an internal 64 bit clock counter which can be read into 
  2915. EDX:EAX using the instruction RDTSC (read time stamp counter). This is very
  2916. useful for testing exactly how many clock cycles a piece of code takes.
  2917.  
  2918. The program below is useful for measuring the number of clock cycles a piece
  2919. of code takes. The program executes the code to test 10 times and stores the
  2920. 10 clock counts. The program can be used in both 16 and 32 bit mode.
  2921.  
  2922. RDTSC   MACRO                   ; define RDTSC instruction
  2923.         DB      0FH,31H
  2924. ENDM
  2925.  
  2926. ITER    EQU     10              ; number of iterations
  2927.  
  2928. .DATA                           ; data segment
  2929. ALIGN   4
  2930. COUNTER DD      0               ; loop counter
  2931. TICS    DD      0               ; temporary storage of clock
  2932. RESULTLIST  DD  ITER DUP (0)    ; list of test results
  2933.  
  2934. .CODE                           ; code segment
  2935. BEGIN:  MOV     [COUNTER],0     ; reset loop counter
  2936. TESTLOOP:                       ; test loop
  2937. ;****************   Do any initializations here:    ************************
  2938.         FINIT
  2939. ;****************   End of initializations          ************************
  2940.         RDTSC                   ; read clock counter
  2941.         MOV     [TICS],EAX      ; save count
  2942.         CLD                     ; non-pairable filler
  2943. REPT    8
  2944.         NOP                     ; eight NOP's to avoid shadowing effect
  2945. ENDM
  2946.  
  2947. ;****************   Put instructions to test here:  ************************
  2948.         FLDPI                   ; this is only an example
  2949.         FSQRT
  2950.         RCR     EBX,10
  2951.         FSTP    ST
  2952. ;********************* End of instructions to test  ************************
  2953.  
  2954.         CLC                     ; non-pairable filler with shadow
  2955.         RDTSC                   ; read counter again
  2956.         SUB     EAX,[TICS]      ; compute difference
  2957.         SUB     EAX,15          ; subtract the clock cycles used by fillers etc
  2958.         MOV     EDX,[COUNTER]   ; loop counter
  2959.         MOV     [RESULTLIST][EDX],EAX   ; store result in table
  2960.         ADD     EDX,TYPE RESULTLIST     ; increment counter
  2961.         MOV     [COUNTER],EDX           ; store counter
  2962.         CMP     EDX,ITER * (TYPE RESULTLIST)
  2963.         JB      TESTLOOP                ; repeat ITER times
  2964.  
  2965. ; insert here code to read out the values in RESULTLIST
  2966.  
  2967.  
  2968. The 'filler' instructions before and after the piece of code to test are 
  2969. critical. The CLD is a non-pairable instruction which has been inserted to 
  2970. make sure the pairing is the same the first time as the subsequent times. 
  2971. The eight NOP instructions are inserted to prevent any prefixes in the code 
  2972. to test to be decoded in the shadow of the preceding instructions. Single 
  2973. byte instructions are used here to obtain the same pairing the first time as 
  2974. the subsequent times. The CLC after the code to test is a non-pairable
  2975. instruction which has a shadow under which the 0FH prefix of the RDTSC can 
  2976. be decoded so that it is independent of any shadowing effect from the code 
  2977. to test.
  2978.  
  2979. On the PentiumPro you have to put in a serializing instruction like CPUID
  2980. before and after each RDTSC to prevent it from executing in parallel with 
  2981. anything else. CPUID has a decoding delay on the Pentium without MMX because 
  2982. of the 0FH prefix, but it has no shadow because it is serializing.
  2983.  
  2984. The RDTSC instruction cannot execute in virtual mode, so if you are running 
  2985. under DOS you must skip the EMM386 (or any other memory manager) in your
  2986. CONFIG.SYS and not run under a DOS box in Windows.
  2987.  
  2988. The Pentium processor has special performance monitor counters which can 
  2989. count events such as cache misses, misalignments, AGI stalls, etc. Details 
  2990. about how to use the performance monitor counters are not covered by this 
  2991. manual and must be sought elsewhere (see chapter 2).
  2992.  
  2993.  
  2994. 23. CONSIDERATIONS FOR OTHER MICROPROCESSORS
  2995. ============================================
  2996. Most of the optimations described in this document have little or no 
  2997. negative effects on other microprocessors, including non-Intel processors, 
  2998. but there are some problems to be aware of.  
  2999.  
  3000. Using a full register after writing to part of the register will cause a
  3001. moderate delay on the 80486 and a severe delay on the PentiumPro and
  3002. PentiumII. This is called a partial register stall. Example:
  3003. MOV AL,[EBX] / MOV ECX,EAX
  3004. You may avoid this penalty by zeroing the full register first:
  3005. XOR EAX,EAX / MOV AL,[EBX] / MOV ECX,EAX
  3006. or by using  MOVZX EAX,BYTE PTR [EBX]
  3007. A similar penalty occurs when you address the same piece of memory with
  3008. different data sizes. Example:
  3009. MOV [ESI],EAX / MOV BL,[ESI]
  3010.  
  3011. Scheduling floating point code for the Pentium often requires a lot of extra
  3012. FXCH instructions. This will slow down execution on earlier microprocessors,
  3013. but not on the PentiumPro and advanced non-Intel processors.
  3014.  
  3015. The MMX instructions available on the PentiumMMX and PentiumII processors
  3016. are very useful for massively parallel integer calculations.
  3017.  
  3018. The PentiumPro chip is faster than the Pentium in some respects, but
  3019. inferior in other respects. Knowing the strong and weak sides of the
  3020. PentiumPro can help you make your code work well on both processors.
  3021.  
  3022. The most important advantage of the PentiumPro is that it does much of the 
  3023. optimation for you: reordering instructions and splitting complex 
  3024. instructions into simple ones. But for perfectly optimized code there is 
  3025. less difference between the two processors.  
  3026.  
  3027. The two processors have basically the same number of execution units, so
  3028. the throughput should be near the same. The PPro has separate units for
  3029. memory read and write so that it can do three operations simultaneously
  3030. if one of them is a memory read, but on the other hand it cannot do two
  3031. memory reads or two writes simultaneously as the Pentium can.
  3032.  
  3033. The PPro is better than the Pentium in the following respects:
  3034.  
  3035. - out of order execution
  3036.  
  3037. - splitting complex instructions into smaller micro-ops
  3038.  
  3039. - one cache miss does not delay subsequent independent instructions
  3040.  
  3041. - automatic register renaming to avoid unnecessary dependencies
  3042.  
  3043. - better jump prediction method than Pentium without MMX
  3044.  
  3045. - many instructions which are unpairable and poorly optimized on the
  3046.   Pentium perform better on the PPro, f.ex. integer multiplication,
  3047.   movzx, cdq, bit scan, bit test, shifts by cl, and floating point store
  3048.  
  3049. - floating point instructions and simple integer instructions can execute
  3050.   simultaneously
  3051.  
  3052. - memory reads and writes do not occupy the ALU's
  3053.  
  3054. - indirect memory read instructions have no AGI stall
  3055.  
  3056. - new conditional move instructions can be used instead of branches in
  3057.   some cases
  3058.  
  3059. - new FCOMI instruction eliminates the need for the slow FNSTSW AX
  3060.  
  3061. The PPro is inferior to the Pentium in the following respects:
  3062.  
  3063. - mispredicted jumps are very expensive (10-15 clock cycles!)
  3064.  
  3065. - poor performance on 16 bit code and segmented models
  3066.  
  3067. - prefixes are expensive (except 0FH extended opcode)
  3068.  
  3069. - long stall when mixing 8, 16, and 32 bit registers
  3070.  
  3071. - fadd, fsub, fmul, fchs have longer latency
  3072.  
  3073. - cannot do two memory reads or two memory writes simultaneously
  3074.  
  3075. - some instruction combinations cannot execute in parallel, like
  3076.   push+push, push+call, compare+conditional jump
  3077.  
  3078. As a consequence of this, the Pentium Pro may actually be slower than the 
  3079. Pentium on perfectly optimized code with a lot of unpredictable branches, 
  3080. and a lot of floating point code with little or no natural parallelism.
  3081. In most other cases the PPro is faster.
  3082.  
  3083. Most of the drawbacks of each processor can be circumvented by careful 
  3084. optimation and running 32 bit flat mode. But the problem with mispredicted 
  3085. jumps on the PPro cannot be avoided except in the cases where you can use
  3086. a conditional move instead.
  3087.  
  3088. Taking advantage of the new instructions in the MMX and PentiumPro 
  3089. processors will create problems if you want your code to be compatible
  3090. with earlier microprocessors. The solution may be to write several
  3091. versions of your code, each optimized for a particular processor. Your
  3092. program should automatically detect which processor it is running on and
  3093. select the appropriate version of code. Such a complicated approach is of
  3094. course only needed for the most critical parts of your program.
  3095.  
  3096.